@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.
@@ -0,0 +1,326 @@
1
+ // @generated by protoc-gen-es v2.12.0 with parameter "target=js+dts,import_extension=js"
2
+ // @generated from file kusinta/iot/link/v1/link.proto (package kusinta.iot.link.v1, syntax proto3)
3
+ /* eslint-disable */
4
+
5
+ import type { GenEnum, GenFile, GenMessage } from "@bufbuild/protobuf/codegenv2";
6
+ import type { Message } from "@bufbuild/protobuf";
7
+ import type { DeviceId } from "../../identity/v1/identity_pb.js";
8
+ import type { Timestamp } from "@bufbuild/protobuf/wkt";
9
+ import type { AttributeRef } from "../../access/v1/acl_pb.js";
10
+
11
+ /**
12
+ * Describes the file kusinta/iot/link/v1/link.proto.
13
+ */
14
+ export declare const file_kusinta_iot_link_v1_link: GenFile;
15
+
16
+ /**
17
+ * One device leading another.
18
+ *
19
+ * @generated from message kusinta.iot.link.v1.DeviceLink
20
+ */
21
+ export declare type DeviceLink = Message<"kusinta.iot.link.v1.DeviceLink"> & {
22
+ /**
23
+ * @generated from field: string link_id = 1;
24
+ */
25
+ linkId: string;
26
+
27
+ /**
28
+ * Which device leads. This is the control surface for the pair: for a climate
29
+ * link, the setpoint that governs both is written here.
30
+ *
31
+ * @generated from field: kusinta.iot.identity.v1.DeviceId sender = 2;
32
+ */
33
+ sender?: DeviceId | undefined;
34
+
35
+ /**
36
+ * Which device follows. One sender may lead several receivers — a room with
37
+ * more than one radiator is the ordinary case — and each is its own link.
38
+ * Several senders leading one receiver is not modelled: combining two
39
+ * measurements needs a policy, and no policy is defined.
40
+ *
41
+ * @generated from field: kusinta.iot.identity.v1.DeviceId receiver = 3;
42
+ */
43
+ receiver?: DeviceId | undefined;
44
+
45
+ /**
46
+ * @generated from field: kusinta.iot.link.v1.LinkFunction function = 4;
47
+ */
48
+ function: LinkFunction;
49
+
50
+ /**
51
+ * @generated from field: kusinta.iot.link.v1.LinkMode mode = 5;
52
+ */
53
+ mode: LinkMode;
54
+
55
+ /**
56
+ * @generated from field: kusinta.iot.link.v1.LinkState state = 6;
57
+ */
58
+ state: LinkState;
59
+
60
+ /**
61
+ * @generated from field: google.protobuf.Timestamp created_at = 7;
62
+ */
63
+ createdAt?: Timestamp | undefined;
64
+
65
+ /**
66
+ * Why the link is not carrying, when state says it is not. Free text for a
67
+ * person, never parsed.
68
+ *
69
+ * @generated from field: string state_detail = 8;
70
+ */
71
+ stateDetail: string;
72
+ };
73
+
74
+ /**
75
+ * Describes the message kusinta.iot.link.v1.DeviceLink.
76
+ * Use `create(DeviceLinkSchema)` to create a new message.
77
+ */
78
+ export declare const DeviceLinkSchema: GenMessage<DeviceLink>;
79
+
80
+ /**
81
+ * What a device can be linked as, declared by the connector that models it.
82
+ *
83
+ * Without this an interface cannot offer a sensible choice: it has no way to know
84
+ * which of two devices may lead, whether a hub can broker them, or which
85
+ * attribute carries the quantity in question. Matching is mechanical — the same
86
+ * function, opposite directions, and a mode both ends support.
87
+ *
88
+ * Declared per device rather than per endpoint. Endpoint would be more precise,
89
+ * but the channels a link actually attaches to frequently carry no readings and
90
+ * so are not announced as endpoints at all; a per-endpoint declaration would have
91
+ * nowhere honest to live. The reserved range on DeviceLink is where that would go
92
+ * if a vendor ever needs it.
93
+ *
94
+ * @generated from message kusinta.iot.link.v1.LinkCapability
95
+ */
96
+ export declare type LinkCapability = Message<"kusinta.iot.link.v1.LinkCapability"> & {
97
+ /**
98
+ * @generated from field: kusinta.iot.link.v1.LinkFunction function = 1;
99
+ */
100
+ function: LinkFunction;
101
+
102
+ /**
103
+ * @generated from field: kusinta.iot.link.v1.LinkDirection direction = 2;
104
+ */
105
+ direction: LinkDirection;
106
+
107
+ /**
108
+ * Modes this device supports for this function. A hard link additionally
109
+ * requires the other end to be on the same hub, which this cannot state alone.
110
+ *
111
+ * @generated from field: repeated kusinta.iot.link.v1.LinkMode supported_modes = 3;
112
+ */
113
+ supportedModes: LinkMode[];
114
+
115
+ /**
116
+ * This device's own attribute for this function — the one it reads as a
117
+ * sender, or the one it is driven through as a receiver. Present because the
118
+ * two ends of a link need not speak the same cluster.
119
+ *
120
+ * @generated from field: kusinta.iot.access.v1.AttributeRef attribute = 4;
121
+ */
122
+ attribute?: AttributeRef | undefined;
123
+
124
+ /**
125
+ * Human-readable, from the connector, in whatever locale it was given. For
126
+ * display beside a choice; never matched on.
127
+ *
128
+ * @generated from field: string label = 5;
129
+ */
130
+ label: string;
131
+ };
132
+
133
+ /**
134
+ * Describes the message kusinta.iot.link.v1.LinkCapability.
135
+ * Use `create(LinkCapabilitySchema)` to create a new message.
136
+ */
137
+ export declare const LinkCapabilitySchema: GenMessage<LinkCapability>;
138
+
139
+ /**
140
+ * Every link a caller was shown, in reply to a listing.
141
+ *
142
+ * @generated from message kusinta.iot.link.v1.DeviceLinkList
143
+ */
144
+ export declare type DeviceLinkList = Message<"kusinta.iot.link.v1.DeviceLinkList"> & {
145
+ /**
146
+ * @generated from field: repeated kusinta.iot.link.v1.DeviceLink links = 1;
147
+ */
148
+ links: DeviceLink[];
149
+ };
150
+
151
+ /**
152
+ * Describes the message kusinta.iot.link.v1.DeviceLinkList.
153
+ * Use `create(DeviceLinkListSchema)` to create a new message.
154
+ */
155
+ export declare const DeviceLinkListSchema: GenMessage<DeviceLinkList>;
156
+
157
+ /**
158
+ * What a link makes the sender do to the receiver.
159
+ *
160
+ * A function, not a cluster id, because the two ends do not necessarily speak the
161
+ * same cluster: a wall thermostat reports its temperature as Thermostat
162
+ * LocalTemperature while a bare sensor reports the same quantity as Temperature
163
+ * Measurement MeasuredValue. Each end states its own attribute in its
164
+ * LinkCapability; the function is what says the two belong together.
165
+ *
166
+ * @generated from enum kusinta.iot.link.v1.LinkFunction
167
+ */
168
+ export enum LinkFunction {
169
+ /**
170
+ * @generated from enum value: LINK_FUNCTION_UNSPECIFIED = 0;
171
+ */
172
+ UNSPECIFIED = 0,
173
+
174
+ /**
175
+ * The sender leads the receiver's climate control.
176
+ *
177
+ * Stronger than feeding a measurement, and the difference matters to anything
178
+ * building a UI. Both the sender's measured temperature and its setpoint reach
179
+ * the receiver, and the transfer is one way: the receiver reports the sender's
180
+ * temperature as its own, and a setpoint written to the receiver is accepted
181
+ * and then reverted to the sender's. So the sender is the control surface for
182
+ * the pair, and a setpoint control offered on a linked receiver is one that
183
+ * appears to work and silently undoes itself.
184
+ *
185
+ * @generated from enum value: LINK_FUNCTION_CLIMATE_LEAD = 1;
186
+ */
187
+ CLIMATE_LEAD = 1,
188
+
189
+ /**
190
+ * The sender's open/closed state reaches the receiver, which acts on it —
191
+ * typically a contact telling a valve to stop heating an open room.
192
+ *
193
+ * Not implied by CLIMATE_LEAD: a device that leads a room's climate does not
194
+ * necessarily forward its own window state, and on at least one vendor it does
195
+ * not. Where both are wanted, both are linked.
196
+ *
197
+ * @generated from enum value: LINK_FUNCTION_WINDOW_STATE = 2;
198
+ */
199
+ WINDOW_STATE = 2,
200
+
201
+ /**
202
+ * The sender is an input the receiver acts on — a button or remote.
203
+ *
204
+ * @generated from enum value: LINK_FUNCTION_REMOTE_CONTROL = 3;
205
+ */
206
+ REMOTE_CONTROL = 3,
207
+ }
208
+
209
+ /**
210
+ * Describes the enum kusinta.iot.link.v1.LinkFunction.
211
+ */
212
+ export declare const LinkFunctionSchema: GenEnum<LinkFunction>;
213
+
214
+ /**
215
+ * Which end of a link a device can be.
216
+ *
217
+ * @generated from enum kusinta.iot.link.v1.LinkDirection
218
+ */
219
+ export enum LinkDirection {
220
+ /**
221
+ * @generated from enum value: LINK_DIRECTION_UNSPECIFIED = 0;
222
+ */
223
+ UNSPECIFIED = 0,
224
+
225
+ /**
226
+ * can lead
227
+ *
228
+ * @generated from enum value: LINK_DIRECTION_SOURCE = 1;
229
+ */
230
+ SOURCE = 1,
231
+
232
+ /**
233
+ * can follow
234
+ *
235
+ * @generated from enum value: LINK_DIRECTION_TARGET = 2;
236
+ */
237
+ TARGET = 2,
238
+ }
239
+
240
+ /**
241
+ * Describes the enum kusinta.iot.link.v1.LinkDirection.
242
+ */
243
+ export declare const LinkDirectionSchema: GenEnum<LinkDirection>;
244
+
245
+ /**
246
+ * How a link is carried.
247
+ *
248
+ * @generated from enum kusinta.iot.link.v1.LinkMode
249
+ */
250
+ export enum LinkMode {
251
+ /**
252
+ * @generated from enum value: LINK_MODE_UNSPECIFIED = 0;
253
+ */
254
+ UNSPECIFIED = 0,
255
+
256
+ /**
257
+ * Device to device, brokered by the hub and then carried without it. Survives
258
+ * a gateway outage. Requires both devices on the same hub, and the hub's own
259
+ * support for the function.
260
+ *
261
+ * @generated from enum value: LINK_MODE_HARD = 1;
262
+ */
263
+ HARD = 1,
264
+
265
+ /**
266
+ * Kept by the gateway, which reads one device and writes the other. Works
267
+ * across vendors and across hubs, and is the only option where no hub can
268
+ * broker the pair — at the cost of not surviving a gateway outage.
269
+ *
270
+ * @generated from enum value: LINK_MODE_SOFT = 2;
271
+ */
272
+ SOFT = 2,
273
+ }
274
+
275
+ /**
276
+ * Describes the enum kusinta.iot.link.v1.LinkMode.
277
+ */
278
+ export declare const LinkModeSchema: GenEnum<LinkMode>;
279
+
280
+ /**
281
+ * Whether a link is doing anything.
282
+ *
283
+ * There is deliberately no "created but not yet in effect" state. On current
284
+ * device firmware a link takes effect immediately, and on firmware old enough not
285
+ * to, it never takes effect at all without physical intervention — which is a
286
+ * refusal at creation time, not a state to wait in.
287
+ *
288
+ * Nor should ACTIVE be inferred from the hub reporting a link exists. A hub can
289
+ * report a link as present, unpending and healthy while the devices ignore it
290
+ * entirely; only behaviour distinguishes the two.
291
+ *
292
+ * @generated from enum kusinta.iot.link.v1.LinkState
293
+ */
294
+ export enum LinkState {
295
+ /**
296
+ * @generated from enum value: LINK_STATE_UNSPECIFIED = 0;
297
+ */
298
+ UNSPECIFIED = 0,
299
+
300
+ /**
301
+ * carrying
302
+ *
303
+ * @generated from enum value: LINK_STATE_ACTIVE = 1;
304
+ */
305
+ ACTIVE = 1,
306
+
307
+ /**
308
+ * the sender is unreachable, gone, or the set is incomplete
309
+ *
310
+ * @generated from enum value: LINK_STATE_BROKEN = 2;
311
+ */
312
+ BROKEN = 2,
313
+
314
+ /**
315
+ * the hub and our records disagree, or the hub cannot say
316
+ *
317
+ * @generated from enum value: LINK_STATE_UNKNOWN = 3;
318
+ */
319
+ UNKNOWN = 3,
320
+ }
321
+
322
+ /**
323
+ * Describes the enum kusinta.iot.link.v1.LinkState.
324
+ */
325
+ export declare const LinkStateSchema: GenEnum<LinkState>;
326
+
@@ -0,0 +1,107 @@
1
+ // @generated by protoc-gen-es v2.12.0 with parameter "target=js+dts,import_extension=js"
2
+ // @generated from file kusinta/iot/link/v1/link.proto (package kusinta.iot.link.v1, syntax proto3)
3
+ /* eslint-disable */
4
+
5
+ import { enumDesc, fileDesc, messageDesc, tsEnum } from "@bufbuild/protobuf/codegenv2";
6
+ import { file_google_protobuf_timestamp } from "@bufbuild/protobuf/wkt";
7
+ import { file_kusinta_iot_access_v1_acl } from "../../access/v1/acl_pb.js";
8
+ import { file_kusinta_iot_identity_v1_identity } from "../../identity/v1/identity_pb.js";
9
+
10
+ /**
11
+ * Describes the file kusinta/iot/link/v1/link.proto.
12
+ */
13
+ export const file_kusinta_iot_link_v1_link = /*@__PURE__*/
14
+ fileDesc("Ch5rdXNpbnRhL2lvdC9saW5rL3YxL2xpbmsucHJvdG8SE2t1c2ludGEuaW90LmxpbmsudjEi4gIKCkRldmljZUxpbmsSDwoHbGlua19pZBgBIAEoCRIxCgZzZW5kZXIYAiABKAsyIS5rdXNpbnRhLmlvdC5pZGVudGl0eS52MS5EZXZpY2VJZBIzCghyZWNlaXZlchgDIAEoCzIhLmt1c2ludGEuaW90LmlkZW50aXR5LnYxLkRldmljZUlkEjMKCGZ1bmN0aW9uGAQgASgOMiEua3VzaW50YS5pb3QubGluay52MS5MaW5rRnVuY3Rpb24SKwoEbW9kZRgFIAEoDjIdLmt1c2ludGEuaW90LmxpbmsudjEuTGlua01vZGUSLQoFc3RhdGUYBiABKA4yHi5rdXNpbnRhLmlvdC5saW5rLnYxLkxpbmtTdGF0ZRIuCgpjcmVhdGVkX2F0GAcgASgLMhouZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcBIUCgxzdGF0ZV9kZXRhaWwYCCABKAlKBAgUEB4i+wEKDkxpbmtDYXBhYmlsaXR5EjMKCGZ1bmN0aW9uGAEgASgOMiEua3VzaW50YS5pb3QubGluay52MS5MaW5rRnVuY3Rpb24SNQoJZGlyZWN0aW9uGAIgASgOMiIua3VzaW50YS5pb3QubGluay52MS5MaW5rRGlyZWN0aW9uEjYKD3N1cHBvcnRlZF9tb2RlcxgDIAMoDjIdLmt1c2ludGEuaW90LmxpbmsudjEuTGlua01vZGUSNgoJYXR0cmlidXRlGAQgASgLMiMua3VzaW50YS5pb3QuYWNjZXNzLnYxLkF0dHJpYnV0ZVJlZhINCgVsYWJlbBgFIAEoCSJACg5EZXZpY2VMaW5rTGlzdBIuCgVsaW5rcxgBIAMoCzIfLmt1c2ludGEuaW90LmxpbmsudjEuRGV2aWNlTGluayqPAQoMTGlua0Z1bmN0aW9uEh0KGUxJTktfRlVOQ1RJT05fVU5TUEVDSUZJRUQQABIeChpMSU5LX0ZVTkNUSU9OX0NMSU1BVEVfTEVBRBABEh4KGkxJTktfRlVOQ1RJT05fV0lORE9XX1NUQVRFEAISIAocTElOS19GVU5DVElPTl9SRU1PVEVfQ09OVFJPTBADKmUKDUxpbmtEaXJlY3Rpb24SHgoaTElOS19ESVJFQ1RJT05fVU5TUEVDSUZJRUQQABIZChVMSU5LX0RJUkVDVElPTl9TT1VSQ0UQARIZChVMSU5LX0RJUkVDVElPTl9UQVJHRVQQAipNCghMaW5rTW9kZRIZChVMSU5LX01PREVfVU5TUEVDSUZJRUQQABISCg5MSU5LX01PREVfSEFSRBABEhIKDkxJTktfTU9ERV9TT0ZUEAIqbQoJTGlua1N0YXRlEhoKFkxJTktfU1RBVEVfVU5TUEVDSUZJRUQQABIVChFMSU5LX1NUQVRFX0FDVElWRRABEhUKEUxJTktfU1RBVEVfQlJPS0VOEAISFgoSTElOS19TVEFURV9VTktOT1dOEANCAkgBYgZwcm90bzM", [file_google_protobuf_timestamp, file_kusinta_iot_access_v1_acl, file_kusinta_iot_identity_v1_identity]);
15
+
16
+ /**
17
+ * Describes the message kusinta.iot.link.v1.DeviceLink.
18
+ * Use `create(DeviceLinkSchema)` to create a new message.
19
+ */
20
+ export const DeviceLinkSchema = /*@__PURE__*/
21
+ messageDesc(file_kusinta_iot_link_v1_link, 0);
22
+
23
+ /**
24
+ * Describes the message kusinta.iot.link.v1.LinkCapability.
25
+ * Use `create(LinkCapabilitySchema)` to create a new message.
26
+ */
27
+ export const LinkCapabilitySchema = /*@__PURE__*/
28
+ messageDesc(file_kusinta_iot_link_v1_link, 1);
29
+
30
+ /**
31
+ * Describes the message kusinta.iot.link.v1.DeviceLinkList.
32
+ * Use `create(DeviceLinkListSchema)` to create a new message.
33
+ */
34
+ export const DeviceLinkListSchema = /*@__PURE__*/
35
+ messageDesc(file_kusinta_iot_link_v1_link, 2);
36
+
37
+ /**
38
+ * Describes the enum kusinta.iot.link.v1.LinkFunction.
39
+ */
40
+ export const LinkFunctionSchema = /*@__PURE__*/
41
+ enumDesc(file_kusinta_iot_link_v1_link, 0);
42
+
43
+ /**
44
+ * What a link makes the sender do to the receiver.
45
+ *
46
+ * A function, not a cluster id, because the two ends do not necessarily speak the
47
+ * same cluster: a wall thermostat reports its temperature as Thermostat
48
+ * LocalTemperature while a bare sensor reports the same quantity as Temperature
49
+ * Measurement MeasuredValue. Each end states its own attribute in its
50
+ * LinkCapability; the function is what says the two belong together.
51
+ *
52
+ * @generated from enum kusinta.iot.link.v1.LinkFunction
53
+ */
54
+ export const LinkFunction = /*@__PURE__*/
55
+ tsEnum(LinkFunctionSchema);
56
+
57
+ /**
58
+ * Describes the enum kusinta.iot.link.v1.LinkDirection.
59
+ */
60
+ export const LinkDirectionSchema = /*@__PURE__*/
61
+ enumDesc(file_kusinta_iot_link_v1_link, 1);
62
+
63
+ /**
64
+ * Which end of a link a device can be.
65
+ *
66
+ * @generated from enum kusinta.iot.link.v1.LinkDirection
67
+ */
68
+ export const LinkDirection = /*@__PURE__*/
69
+ tsEnum(LinkDirectionSchema);
70
+
71
+ /**
72
+ * Describes the enum kusinta.iot.link.v1.LinkMode.
73
+ */
74
+ export const LinkModeSchema = /*@__PURE__*/
75
+ enumDesc(file_kusinta_iot_link_v1_link, 2);
76
+
77
+ /**
78
+ * How a link is carried.
79
+ *
80
+ * @generated from enum kusinta.iot.link.v1.LinkMode
81
+ */
82
+ export const LinkMode = /*@__PURE__*/
83
+ tsEnum(LinkModeSchema);
84
+
85
+ /**
86
+ * Describes the enum kusinta.iot.link.v1.LinkState.
87
+ */
88
+ export const LinkStateSchema = /*@__PURE__*/
89
+ enumDesc(file_kusinta_iot_link_v1_link, 3);
90
+
91
+ /**
92
+ * Whether a link is doing anything.
93
+ *
94
+ * There is deliberately no "created but not yet in effect" state. On current
95
+ * device firmware a link takes effect immediately, and on firmware old enough not
96
+ * to, it never takes effect at all without physical intervention — which is a
97
+ * refusal at creation time, not a state to wait in.
98
+ *
99
+ * Nor should ACTIVE be inferred from the hub reporting a link exists. A hub can
100
+ * report a link as present, unpending and healthy while the devices ignore it
101
+ * entirely; only behaviour distinguishes the two.
102
+ *
103
+ * @generated from enum kusinta.iot.link.v1.LinkState
104
+ */
105
+ export const LinkState = /*@__PURE__*/
106
+ tsEnum(LinkStateSchema);
107
+
@@ -236,6 +236,21 @@ export declare type HmMaintenanceProps = Message<"kusinta.iot.vendor.homematic.v
236
236
  * @generated from field: optional bool config_pending = 7;
237
237
  */
238
238
  configPending?: boolean | undefined;
239
+
240
+ /**
241
+ * True while the device has spent its share of the radio band's transmit budget and
242
+ * must wait before sending again. The 868 MHz band permits roughly one percent duty
243
+ * cycle, and it regenerates at about that rate per half minute.
244
+ *
245
+ * Worth carrying rather than leaving to the connector, because a spent budget is
246
+ * indistinguishable from a working device that simply has nothing to say: it stays
247
+ * reachable, reports no error, and silently drops what it was asked to do. Anything
248
+ * that writes on a schedule needs to be able to see this before it concludes a device
249
+ * is ignoring it.
250
+ *
251
+ * @generated from field: optional bool duty_cycle = 8;
252
+ */
253
+ dutyCycle?: boolean | undefined;
239
254
  };
240
255
 
241
256
  /**
@@ -9,7 +9,7 @@ import { file_kusinta_iot_vendor_v1_vendor_options } from "../../v1/vendor_optio
9
9
  * Describes the file kusinta/iot/vendor/homematic/v1/homematic.proto.
10
10
  */
11
11
  export const file_kusinta_iot_vendor_homematic_v1_homematic = /*@__PURE__*/
12
- fileDesc("Ci9rdXNpbnRhL2lvdC92ZW5kb3IvaG9tZW1hdGljL3YxL2hvbWVtYXRpYy5wcm90bxIfa3VzaW50YS5pb3QudmVuZG9yLmhvbWVtYXRpYy52MSI4ChdIb21lbWF0aWNEZXZpY2VJZGVudGl0eRIPCgdhZGRyZXNzGAEgASgJEgwKBHR5cGUYAiABKAki/wYKEUhtVGhlcm1vc3RhdFByb3BzEisKCmJvb3N0X21vZGUYASABKAhCEqK1GApCT09TVF9NT0RF0LUYBkgAiAEBEjUKFGJvb3N0X3RpbWVfcmVtYWluaW5nGAIgASgNQhKitRgKQk9PU1RfVElNRdC1GAVIAYgBARIvCgxjb250cm9sX21vZGUYAyABKA1CFKK1GAxDT05UUk9MX01PREXQtRgCSAKIAQESNwoQZnJvc3RfcHJvdGVjdGlvbhgEIAEoCEIYorUYEEZST1NUX1BST1RFQ1RJT07QtRgFSAOIAQESKwoKcGFydHlfbW9kZRgFIAEoCEISorUYClBBUlRZX01PREXQtRgFSASIAQESLwoMd2luZG93X3N0YXRlGAcgASgNQhSitRgMV0lORE9XX1NUQVRF0LUYB0gFiAEBEi0KC3ZhbHZlX3N0YXRlGAggASgNQhOitRgLVkFMVkVfU1RBVEXQtRgFSAaIAQESMwoOc2V0X3BvaW50X21vZGUYCSABKA1CFqK1GA5TRVRfUE9JTlRfTU9ERdC1GAdIB4gBARIzCg5hY3RpdmVfcHJvZmlsZRgKIAEoDUIWorUYDkFDVElWRV9QUk9GSUxF0LUYB0gIiAEBEkkKGWFjdHVhbF90ZW1wZXJhdHVyZV9zdGF0dXMYCyABKA1CIaK1GBlBQ1RVQUxfVEVNUEVSQVRVUkVfU1RBVFVT0LUYBUgJiAEBEjMKDnZhbHZlX2FkYXB0aW9uGAwgASgIQhaitRgOVkFMVkVfQURBUFRJT07QtRgHSAqIAQE6GKq1GBRob21lbWF0aWMudGhlcm1vc3RhdEINCgtfYm9vc3RfbW9kZUIXChVfYm9vc3RfdGltZV9yZW1haW5pbmdCDwoNX2NvbnRyb2xfbW9kZUITChFfZnJvc3RfcHJvdGVjdGlvbkINCgtfcGFydHlfbW9kZUIPCg1fd2luZG93X3N0YXRlQg4KDF92YWx2ZV9zdGF0ZUIRCg9fc2V0X3BvaW50X21vZGVCEQoPX2FjdGl2ZV9wcm9maWxlQhwKGl9hY3R1YWxfdGVtcGVyYXR1cmVfc3RhdHVzQhEKD192YWx2ZV9hZGFwdGlvbkoECAYQB1IFbGV2ZWxSFmN1cnJlbnRfcHJvZmlsZV9wZXJpb2RSEWJvb3N0X3RpbWVfcGVyaW9kIvoDChJIbU1haW50ZW5hbmNlUHJvcHMSKwoKZXJyb3JfY29kZRgBIAEoDUISorUYCkVSUk9SX0NPREXQtRgFSACIAQESJwoIc2Fib3RhZ2UYAiABKAhCEKK1GAhTQUJPVEFHRdC1GAVIAYgBARItCgtyc3NpX2RldmljZRgDIAEoEUITorUYC1JTU0lfREVWSUNF0LUYBUgCiAEBEikKCXJzc2lfcGVlchgEIAEoEUIRorUYCVJTU0lfUEVFUtC1GAVIA4gBARJHChhvcGVyYXRpbmdfdm9sdGFnZV9zdGF0dXMYBSABKA1CIKK1GBhPUEVSQVRJTkdfVk9MVEFHRV9TVEFUVVPQtRgFSASIAQESJQoHdW5yZWFjaBgGIAEoCEIPorUYB1VOUkVBQ0jQtRgFSAWIAQESMwoOY29uZmlnX3BlbmRpbmcYByABKAhCFqK1GA5DT05GSUdfUEVORElOR9C1GAVIBogBAToZqrUYFWhvbWVtYXRpYy5tYWludGVuYW5jZUINCgtfZXJyb3JfY29kZUILCglfc2Fib3RhZ2VCDgoMX3Jzc2lfZGV2aWNlQgwKCl9yc3NpX3BlZXJCGwoZX29wZXJhdGluZ192b2x0YWdlX3N0YXR1c0IKCghfdW5yZWFjaEIRCg9fY29uZmlnX3BlbmRpbmdCAkgBYgZwcm90bzM", [file_kusinta_iot_vendor_v1_vendor_options]);
12
+ fileDesc("Ci9rdXNpbnRhL2lvdC92ZW5kb3IvaG9tZW1hdGljL3YxL2hvbWVtYXRpYy5wcm90bxIfa3VzaW50YS5pb3QudmVuZG9yLmhvbWVtYXRpYy52MSI4ChdIb21lbWF0aWNEZXZpY2VJZGVudGl0eRIPCgdhZGRyZXNzGAEgASgJEgwKBHR5cGUYAiABKAki/wYKEUhtVGhlcm1vc3RhdFByb3BzEisKCmJvb3N0X21vZGUYASABKAhCEqK1GApCT09TVF9NT0RF0LUYBkgAiAEBEjUKFGJvb3N0X3RpbWVfcmVtYWluaW5nGAIgASgNQhKitRgKQk9PU1RfVElNRdC1GAVIAYgBARIvCgxjb250cm9sX21vZGUYAyABKA1CFKK1GAxDT05UUk9MX01PREXQtRgCSAKIAQESNwoQZnJvc3RfcHJvdGVjdGlvbhgEIAEoCEIYorUYEEZST1NUX1BST1RFQ1RJT07QtRgFSAOIAQESKwoKcGFydHlfbW9kZRgFIAEoCEISorUYClBBUlRZX01PREXQtRgFSASIAQESLwoMd2luZG93X3N0YXRlGAcgASgNQhSitRgMV0lORE9XX1NUQVRF0LUYB0gFiAEBEi0KC3ZhbHZlX3N0YXRlGAggASgNQhOitRgLVkFMVkVfU1RBVEXQtRgFSAaIAQESMwoOc2V0X3BvaW50X21vZGUYCSABKA1CFqK1GA5TRVRfUE9JTlRfTU9ERdC1GAdIB4gBARIzCg5hY3RpdmVfcHJvZmlsZRgKIAEoDUIWorUYDkFDVElWRV9QUk9GSUxF0LUYB0gIiAEBEkkKGWFjdHVhbF90ZW1wZXJhdHVyZV9zdGF0dXMYCyABKA1CIaK1GBlBQ1RVQUxfVEVNUEVSQVRVUkVfU1RBVFVT0LUYBUgJiAEBEjMKDnZhbHZlX2FkYXB0aW9uGAwgASgIQhaitRgOVkFMVkVfQURBUFRJT07QtRgHSAqIAQE6GKq1GBRob21lbWF0aWMudGhlcm1vc3RhdEINCgtfYm9vc3RfbW9kZUIXChVfYm9vc3RfdGltZV9yZW1haW5pbmdCDwoNX2NvbnRyb2xfbW9kZUITChFfZnJvc3RfcHJvdGVjdGlvbkINCgtfcGFydHlfbW9kZUIPCg1fd2luZG93X3N0YXRlQg4KDF92YWx2ZV9zdGF0ZUIRCg9fc2V0X3BvaW50X21vZGVCEQoPX2FjdGl2ZV9wcm9maWxlQhwKGl9hY3R1YWxfdGVtcGVyYXR1cmVfc3RhdHVzQhEKD192YWx2ZV9hZGFwdGlvbkoECAYQB1IFbGV2ZWxSFmN1cnJlbnRfcHJvZmlsZV9wZXJpb2RSEWJvb3N0X3RpbWVfcGVyaW9kIrYEChJIbU1haW50ZW5hbmNlUHJvcHMSKwoKZXJyb3JfY29kZRgBIAEoDUISorUYCkVSUk9SX0NPREXQtRgFSACIAQESJwoIc2Fib3RhZ2UYAiABKAhCEKK1GAhTQUJPVEFHRdC1GAVIAYgBARItCgtyc3NpX2RldmljZRgDIAEoEUITorUYC1JTU0lfREVWSUNF0LUYBUgCiAEBEikKCXJzc2lfcGVlchgEIAEoEUIRorUYCVJTU0lfUEVFUtC1GAVIA4gBARJHChhvcGVyYXRpbmdfdm9sdGFnZV9zdGF0dXMYBSABKA1CIKK1GBhPUEVSQVRJTkdfVk9MVEFHRV9TVEFUVVPQtRgFSASIAQESJQoHdW5yZWFjaBgGIAEoCEIPorUYB1VOUkVBQ0jQtRgFSAWIAQESMwoOY29uZmlnX3BlbmRpbmcYByABKAhCFqK1GA5DT05GSUdfUEVORElOR9C1GAVIBogBARIrCgpkdXR5X2N5Y2xlGAggASgIQhKitRgKRFVUWV9DWUNMRdC1GAVIB4gBAToZqrUYFWhvbWVtYXRpYy5tYWludGVuYW5jZUINCgtfZXJyb3JfY29kZUILCglfc2Fib3RhZ2VCDgoMX3Jzc2lfZGV2aWNlQgwKCl9yc3NpX3BlZXJCGwoZX29wZXJhdGluZ192b2x0YWdlX3N0YXR1c0IKCghfdW5yZWFjaEIRCg9fY29uZmlnX3BlbmRpbmdCDQoLX2R1dHlfY3ljbGVCAkgBYgZwcm90bzM", [file_kusinta_iot_vendor_v1_vendor_options]);
13
13
 
14
14
  /**
15
15
  * Describes the message kusinta.iot.vendor.homematic.v1.HomematicDeviceIdentity.
@@ -8,6 +8,7 @@ import type { ConnectorId, DeviceId, SpaceId } from "../../identity/v1/identity_
8
8
  import type { AttributeRef } from "../../access/v1/acl_pb.js";
9
9
  import type { Space } from "../../space/v1/space_pb.js";
10
10
  import type { ManagementAck, ManagementRequest, SpaceTree } from "./management_pb.js";
11
+ import type { DeviceLink, DeviceLinkList } from "../../link/v1/link_pb.js";
11
12
  import type { PairingErrorDetail, PairingWindow } from "../../common/v1/pairing_pb.js";
12
13
  import type { DeviceOwnershipType } from "../../common/v1/types_pb.js";
13
14
  import type { Timestamp } from "@bufbuild/protobuf/wkt";
@@ -318,6 +319,14 @@ export declare type ManagementResult = Message<"kusinta.iot.webrtc.v1.Management
318
319
  */
319
320
  value: ManagementAck;
320
321
  case: "ack";
322
+ } | {
323
+ /**
324
+ * list_device_links
325
+ *
326
+ * @generated from field: kusinta.iot.link.v1.DeviceLinkList links = 6;
327
+ */
328
+ value: DeviceLinkList;
329
+ case: "links";
321
330
  } | { case: undefined; value?: undefined };
322
331
  };
323
332
 
@@ -480,7 +489,52 @@ export declare const PairingFinishedSchema: GenMessage<PairingFinished>;
480
489
 
481
490
  /**
482
491
  * GatewayMessage: gateway → app
492
+ * A link between two devices has changed, gateway to app.
493
+ *
494
+ * Sent without being asked for, like device_added, and for the same reason: a link's
495
+ * state is not settled when it is made. A hub accepting a link is not the two devices
496
+ * honouring it, and a link that was carrying stops when its sender goes quiet — so the
497
+ * interesting transitions all happen long after the request that created it was
498
+ * answered. Without this an app can only learn by listing every link again and
499
+ * diffing, which means a room that has quietly stopped following its wall thermostat
500
+ * looks correct until somebody reloads.
501
+ *
502
+ * Apply as an upsert keyed on link.link_id, never as an insert: the same link is sent
503
+ * again whenever its state moves.
483
504
  *
505
+ * Sent only for links the recipient is entitled to see. An unfiltered one would say
506
+ * which devices exist and how they are arranged, to somebody entitled to neither.
507
+ *
508
+ * @generated from message kusinta.iot.webrtc.v1.LinkChanged
509
+ */
510
+ export declare type LinkChanged = Message<"kusinta.iot.webrtc.v1.LinkChanged"> & {
511
+ /**
512
+ * @generated from field: kusinta.iot.link.v1.DeviceLink link = 1;
513
+ */
514
+ link?: DeviceLink | undefined;
515
+
516
+ /**
517
+ * The link is gone, rather than merely not carrying. Distinct from a BROKEN state
518
+ * because the two need opposite responses: a removal is finished business, while a
519
+ * link that has stopped carrying is a fault worth showing somebody. Announcing a
520
+ * deletion as BROKEN would leave every removed link looking like something to go
521
+ * and repair.
522
+ *
523
+ * `link` still carries the whole link when this is set, so the app can name what
524
+ * went rather than only its id.
525
+ *
526
+ * @generated from field: bool removed = 2;
527
+ */
528
+ removed: boolean;
529
+ };
530
+
531
+ /**
532
+ * Describes the message kusinta.iot.webrtc.v1.LinkChanged.
533
+ * Use `create(LinkChangedSchema)` to create a new message.
534
+ */
535
+ export declare const LinkChangedSchema: GenMessage<LinkChanged>;
536
+
537
+ /**
484
538
  * @generated from message kusinta.iot.webrtc.v1.GatewayMessage
485
539
  */
486
540
  export declare type GatewayMessage = Message<"kusinta.iot.webrtc.v1.GatewayMessage"> & {
@@ -586,6 +640,12 @@ export declare type GatewayMessage = Message<"kusinta.iot.webrtc.v1.GatewayMessa
586
640
  */
587
641
  value: PairingFinished;
588
642
  case: "pairingFinished";
643
+ } | {
644
+ /**
645
+ * @generated from field: kusinta.iot.webrtc.v1.LinkChanged link_changed = 19;
646
+ */
647
+ value: LinkChanged;
648
+ case: "linkChanged";
589
649
  } | { case: undefined; value?: undefined };
590
650
  };
591
651
 
@@ -9,6 +9,7 @@ import { file_kusinta_iot_common_v1_pairing } from "../../common/v1/pairing_pb.j
9
9
  import { file_kusinta_iot_common_v1_types } from "../../common/v1/types_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_identity_v1_identity } from "../../identity/v1/identity_pb.js";
12
+ import { file_kusinta_iot_link_v1_link } from "../../link/v1/link_pb.js";
12
13
  import { file_kusinta_iot_space_v1_space } from "../../space/v1/space_pb.js";
13
14
  import { file_kusinta_iot_webrtc_v1_command } from "./command_pb.js";
14
15
  import { file_kusinta_iot_webrtc_v1_device_state } from "./device_state_pb.js";
@@ -19,7 +20,7 @@ import { file_kusinta_iot_webrtc_v1_permission_push } from "./permission_push_pb
19
20
  * Describes the file kusinta/iot/webrtc/v1/envelope.proto.
20
21
  */
21
22
  export const file_kusinta_iot_webrtc_v1_envelope = /*@__PURE__*/
22
- fileDesc("CiRrdXNpbnRhL2lvdC93ZWJydGMvdjEvZW52ZWxvcGUucHJvdG8SFWt1c2ludGEuaW90LndlYnJ0Yy52MSIGCgRQaW5nIgYKBFBvbmciIwoRSGFuZHNoYWtlUmVqZWN0ZWQSDgoGcmVhc29uGAEgASgJIlwKDEFwcEhhbmRzaGFrZRILCgNqd3QYASABKAkSPwoUc3Vic2NyaWJlX2RldmljZV9pZHMYAiADKAsyIS5rdXNpbnRhLmlvdC5pZGVudGl0eS52MS5EZXZpY2VJZCJJChBTdWJzY3JpYmVEZXZpY2VzEjUKCmRldmljZV9pZHMYASADKAsyIS5rdXNpbnRhLmlvdC5pZGVudGl0eS52MS5EZXZpY2VJZCJLChJVbnN1YnNjcmliZURldmljZXMSNQoKZGV2aWNlX2lkcxgBIAMoCzIhLmt1c2ludGEuaW90LmlkZW50aXR5LnYxLkRldmljZUlkIpMBChNSZWZ1c2VkU3Vic2NyaXB0aW9uEjQKCWRldmljZV9pZBgBIAEoCzIhLmt1c2ludGEuaW90LmlkZW50aXR5LnYxLkRldmljZUlkEjUKBGNvZGUYAiABKA4yJy5rdXNpbnRhLmlvdC53ZWJydGMudjEuR2F0ZXdheUVycm9yQ29kZRIPCgdtZXNzYWdlGAMgASgJIpoBCg9TdWJzY3JpcHRpb25BY2sSEwoLaW5fcmVwbHlfdG8YASABKAkSNQoKc3Vic2NyaWJlZBgCIAMoCzIhLmt1c2ludGEuaW90LmlkZW50aXR5LnYxLkRldmljZUlkEjsKB3JlZnVzZWQYAyADKAsyKi5rdXNpbnRhLmlvdC53ZWJydGMudjEuUmVmdXNlZFN1YnNjcmlwdGlvbiLRAQoTUHJvcGVydHlSZWFkUmVxdWVzdBI0CglkZXZpY2VfaWQYASABKAsyIS5rdXNpbnRhLmlvdC5pZGVudGl0eS52MS5EZXZpY2VJZBIzCgZ0YXJnZXQYByABKAsyIy5rdXNpbnRhLmlvdC5hY2Nlc3MudjEuQXR0cmlidXRlUmVmSgQIAhAHUg5hdHRyaWJ1dGVfbmFtZVIOY2x1c3Rlcl9pZF9oZXhSCmNsdXN0ZXJfaWRSC2VuZHBvaW50X2lkUhB2ZW5kb3JfZXh0ZW5zaW9uIswBCgxHYXRld2F5RXJyb3ISNQoEY29kZRgBIAEoDjInLmt1c2ludGEuaW90LndlYnJ0Yy52MS5HYXRld2F5RXJyb3JDb2RlEg8KB21lc3NhZ2UYAiABKAkSQwoIbWV0YWRhdGEYAyADKAsyMS5rdXNpbnRhLmlvdC53ZWJydGMudjEuR2F0ZXdheUVycm9yLk1ldGFkYXRhRW50cnkaLwoNTWV0YWRhdGFFbnRyeRILCgNrZXkYASABKAkSDQoFdmFsdWUYAiABKAk6AjgBIoICChBNYW5hZ2VtZW50UmVzdWx0EhMKC2luX3JlcGx5X3RvGAEgASgJEjQKBWVycm9yGAIgASgLMiMua3VzaW50YS5pb3Qud2VicnRjLnYxLkdhdGV3YXlFcnJvckgAEiwKBXNwYWNlGAMgASgLMhsua3VzaW50YS5pb3Quc3BhY2UudjEuU3BhY2VIABI2CgpzcGFjZV90cmVlGAQgASgLMiAua3VzaW50YS5pb3Qud2VicnRjLnYxLlNwYWNlVHJlZUgAEjMKA2FjaxgFIAEoCzIkLmt1c2ludGEuaW90LndlYnJ0Yy52MS5NYW5hZ2VtZW50QWNrSABCCAoGcmVzdWx0IvsBCgxTdGFydFBhaXJpbmcSOgoMY29ubmVjdG9yX2lkGAEgASgLMiQua3VzaW50YS5pb3QuaWRlbnRpdHkudjEuQ29ubmVjdG9ySWQSNAoGd2luZG93GAIgASgLMiQua3VzaW50YS5pb3QuY29tbW9uLnYxLlBhaXJpbmdXaW5kb3cSOgoQaW5pdGlhbF9zcGFjZV9pZBgDIAEoCzIgLmt1c2ludGEuaW90LmlkZW50aXR5LnYxLlNwYWNlSWQSPQoJb3duZXJzaGlwGAQgASgOMioua3VzaW50YS5pb3QuY29tbW9uLnYxLkRldmljZU93bmVyc2hpcFR5cGUijwEKDlBhaXJpbmdTdGFydGVkEhMKC2luX3JlcGx5X3RvGAEgASgJEi4KCmV4cGlyZXNfYXQYAiABKAsyGi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wEjgKBWVycm9yGAMgASgLMikua3VzaW50YS5pb3QuY29tbW9uLnYxLlBhaXJpbmdFcnJvckRldGFpbCKXAQoPUGFpcmluZ0ZpbmlzaGVkEhMKC2luX3JlcGx5X3RvGAEgASgJEjUKCmRldmljZV9pZHMYAiADKAsyIS5rdXNpbnRhLmlvdC5pZGVudGl0eS52MS5EZXZpY2VJZBI4CgVlcnJvchgDIAEoCzIpLmt1c2ludGEuaW90LmNvbW1vbi52MS5QYWlyaW5nRXJyb3JEZXRhaWwimwgKDkdhdGV3YXlNZXNzYWdlEhIKCm1lc3NhZ2VfaWQYASABKAkSKwoHc2VudF9hdBgCIAEoCzIaLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXASRAoOc3RhdGVfc25hcHNob3QYAyABKAsyKi5rdXNpbnRhLmlvdC53ZWJydGMudjEuRGV2aWNlU3RhdGVTbmFwc2hvdEgAEkAKD3Byb3BlcnR5X3JlcG9ydBgEIAEoCzIlLmt1c2ludGEuaW90LndlYnJ0Yy52MS5Qcm9wZXJ0eVJlcG9ydEgAEkgKEXBlcm1pc3Npb25fdXBkYXRlGAUgASgLMisua3VzaW50YS5pb3Qud2VicnRjLnYxLkxpdmVQZXJtaXNzaW9uVXBkYXRlSAASPgoOY29tbWFuZF9yZXN1bHQYBiABKAsyJC5rdXNpbnRhLmlvdC53ZWJydGMudjEuQ29tbWFuZFJlc3VsdEgAEisKBHBvbmcYCCABKAsyGy5rdXNpbnRhLmlvdC53ZWJydGMudjEuUG9uZ0gAEkYKEmhhbmRzaGFrZV9yZWplY3RlZBgJIAEoCzIoLmt1c2ludGEuaW90LndlYnJ0Yy52MS5IYW5kc2hha2VSZWplY3RlZEgAEjQKBWVycm9yGAogASgLMiMua3VzaW50YS5pb3Qud2VicnRjLnYxLkdhdGV3YXlFcnJvckgAEkIKEHN1YnNjcmlwdGlvbl9hY2sYCyABKAsyJi5rdXNpbnRhLmlvdC53ZWJydGMudjEuU3Vic2NyaXB0aW9uQWNrSAASOgoMZGV2aWNlX2FkZGVkGAwgASgLMiIua3VzaW50YS5pb3Qud2VicnRjLnYxLkRldmljZUFkZGVkSAASPgoOZGV2aWNlX3JlbW92ZWQYDSABKAsyJC5rdXNpbnRhLmlvdC53ZWJydGMudjEuRGV2aWNlUmVtb3ZlZEgAEkQKEW1hbmFnZW1lbnRfcmVzdWx0GA4gASgLMicua3VzaW50YS5pb3Qud2VicnRjLnYxLk1hbmFnZW1lbnRSZXN1bHRIABJACg1kZXZpY2VfZXZlbnRzGBAgASgLMicua3VzaW50YS5pb3QuZGV2aWNlLnYxLkRldmljZUV2ZW50QmF0Y2hIABJACg9wYWlyaW5nX3N0YXJ0ZWQYESABKAsyJS5rdXNpbnRhLmlvdC53ZWJydGMudjEuUGFpcmluZ1N0YXJ0ZWRIABJCChBwYWlyaW5nX2ZpbmlzaGVkGBIgASgLMiYua3VzaW50YS5pb3Qud2VicnRjLnYxLlBhaXJpbmdGaW5pc2hlZEgAQgkKB3BheWxvYWRKBAgPEBBKBAgHEAhSFmF0dHJpYnV0ZV93cml0ZV9yZXN1bHRSDnByb3BlcnR5X2V2ZW50IoMFCgpBcHBNZXNzYWdlEhIKCm1lc3NhZ2VfaWQYASABKAkSKwoHc2VudF9hdBgCIAEoCzIaLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXASOAoJaGFuZHNoYWtlGAMgASgLMiMua3VzaW50YS5pb3Qud2VicnRjLnYxLkFwcEhhbmRzaGFrZUgAEjcKB2NvbW1hbmQYBCABKAsyJC5rdXNpbnRhLmlvdC53ZWJydGMudjEuRGV2aWNlQ29tbWFuZEgAEkIKDHJlYWRfcmVxdWVzdBgFIAEoCzIqLmt1c2ludGEuaW90LndlYnJ0Yy52MS5Qcm9wZXJ0eVJlYWRSZXF1ZXN0SAASKwoEcGluZxgGIAEoCzIbLmt1c2ludGEuaW90LndlYnJ0Yy52MS5QaW5nSAASPAoJc3Vic2NyaWJlGAcgASgLMicua3VzaW50YS5pb3Qud2VicnRjLnYxLlN1YnNjcmliZURldmljZXNIABJACgt1bnN1YnNjcmliZRgIIAEoCzIpLmt1c2ludGEuaW90LndlYnJ0Yy52MS5VbnN1YnNjcmliZURldmljZXNIABI+CgptYW5hZ2VtZW50GAkgASgLMigua3VzaW50YS5pb3Qud2VicnRjLnYxLk1hbmFnZW1lbnRSZXF1ZXN0SAASRwoPYXR0cmlidXRlX3dyaXRlGAogASgLMiwua3VzaW50YS5pb3Qud2VicnRjLnYxLkF0dHJpYnV0ZVdyaXRlUmVxdWVzdEgAEjwKDXN0YXJ0X3BhaXJpbmcYCyABKAsyIy5rdXNpbnRhLmlvdC53ZWJydGMudjEuU3RhcnRQYWlyaW5nSABCCQoHcGF5bG9hZCr2AQoQR2F0ZXdheUVycm9yQ29kZRIiCh5HQVRFV0FZX0VSUk9SX0NPREVfVU5TUEVDSUZJRUQQABIjCh9HQVRFV0FZX0VSUk9SX0NPREVfTk9UX0VOVElUTEVEEAESJgoiR0FURVdBWV9FUlJPUl9DT0RFX0lOVkFMSURfUkVRVUVTVBACEiIKHkdBVEVXQVlfRVJST1JfQ09ERV9VTkFWQUlMQUJMRRADEh8KG0dBVEVXQVlfRVJST1JfQ09ERV9JTlRFUk5BTBAEEiwKKEdBVEVXQVlfRVJST1JfQ09ERV9TRVNTSU9OX0xJTUlUX1JFQUNIRUQQBUICSAFiBnByb3RvMw", [file_google_protobuf_timestamp, file_kusinta_iot_access_v1_acl, file_kusinta_iot_common_v1_pairing, file_kusinta_iot_common_v1_types, file_kusinta_iot_device_v1_device_event, file_kusinta_iot_identity_v1_identity, file_kusinta_iot_space_v1_space, file_kusinta_iot_webrtc_v1_command, file_kusinta_iot_webrtc_v1_device_state, file_kusinta_iot_webrtc_v1_management, file_kusinta_iot_webrtc_v1_permission_push]);
23
+ fileDesc("CiRrdXNpbnRhL2lvdC93ZWJydGMvdjEvZW52ZWxvcGUucHJvdG8SFWt1c2ludGEuaW90LndlYnJ0Yy52MSIGCgRQaW5nIgYKBFBvbmciIwoRSGFuZHNoYWtlUmVqZWN0ZWQSDgoGcmVhc29uGAEgASgJIlwKDEFwcEhhbmRzaGFrZRILCgNqd3QYASABKAkSPwoUc3Vic2NyaWJlX2RldmljZV9pZHMYAiADKAsyIS5rdXNpbnRhLmlvdC5pZGVudGl0eS52MS5EZXZpY2VJZCJJChBTdWJzY3JpYmVEZXZpY2VzEjUKCmRldmljZV9pZHMYASADKAsyIS5rdXNpbnRhLmlvdC5pZGVudGl0eS52MS5EZXZpY2VJZCJLChJVbnN1YnNjcmliZURldmljZXMSNQoKZGV2aWNlX2lkcxgBIAMoCzIhLmt1c2ludGEuaW90LmlkZW50aXR5LnYxLkRldmljZUlkIpMBChNSZWZ1c2VkU3Vic2NyaXB0aW9uEjQKCWRldmljZV9pZBgBIAEoCzIhLmt1c2ludGEuaW90LmlkZW50aXR5LnYxLkRldmljZUlkEjUKBGNvZGUYAiABKA4yJy5rdXNpbnRhLmlvdC53ZWJydGMudjEuR2F0ZXdheUVycm9yQ29kZRIPCgdtZXNzYWdlGAMgASgJIpoBCg9TdWJzY3JpcHRpb25BY2sSEwoLaW5fcmVwbHlfdG8YASABKAkSNQoKc3Vic2NyaWJlZBgCIAMoCzIhLmt1c2ludGEuaW90LmlkZW50aXR5LnYxLkRldmljZUlkEjsKB3JlZnVzZWQYAyADKAsyKi5rdXNpbnRhLmlvdC53ZWJydGMudjEuUmVmdXNlZFN1YnNjcmlwdGlvbiLRAQoTUHJvcGVydHlSZWFkUmVxdWVzdBI0CglkZXZpY2VfaWQYASABKAsyIS5rdXNpbnRhLmlvdC5pZGVudGl0eS52MS5EZXZpY2VJZBIzCgZ0YXJnZXQYByABKAsyIy5rdXNpbnRhLmlvdC5hY2Nlc3MudjEuQXR0cmlidXRlUmVmSgQIAhAHUg5hdHRyaWJ1dGVfbmFtZVIOY2x1c3Rlcl9pZF9oZXhSCmNsdXN0ZXJfaWRSC2VuZHBvaW50X2lkUhB2ZW5kb3JfZXh0ZW5zaW9uIswBCgxHYXRld2F5RXJyb3ISNQoEY29kZRgBIAEoDjInLmt1c2ludGEuaW90LndlYnJ0Yy52MS5HYXRld2F5RXJyb3JDb2RlEg8KB21lc3NhZ2UYAiABKAkSQwoIbWV0YWRhdGEYAyADKAsyMS5rdXNpbnRhLmlvdC53ZWJydGMudjEuR2F0ZXdheUVycm9yLk1ldGFkYXRhRW50cnkaLwoNTWV0YWRhdGFFbnRyeRILCgNrZXkYASABKAkSDQoFdmFsdWUYAiABKAk6AjgBIrgCChBNYW5hZ2VtZW50UmVzdWx0EhMKC2luX3JlcGx5X3RvGAEgASgJEjQKBWVycm9yGAIgASgLMiMua3VzaW50YS5pb3Qud2VicnRjLnYxLkdhdGV3YXlFcnJvckgAEiwKBXNwYWNlGAMgASgLMhsua3VzaW50YS5pb3Quc3BhY2UudjEuU3BhY2VIABI2CgpzcGFjZV90cmVlGAQgASgLMiAua3VzaW50YS5pb3Qud2VicnRjLnYxLlNwYWNlVHJlZUgAEjMKA2FjaxgFIAEoCzIkLmt1c2ludGEuaW90LndlYnJ0Yy52MS5NYW5hZ2VtZW50QWNrSAASNAoFbGlua3MYBiABKAsyIy5rdXNpbnRhLmlvdC5saW5rLnYxLkRldmljZUxpbmtMaXN0SABCCAoGcmVzdWx0IvsBCgxTdGFydFBhaXJpbmcSOgoMY29ubmVjdG9yX2lkGAEgASgLMiQua3VzaW50YS5pb3QuaWRlbnRpdHkudjEuQ29ubmVjdG9ySWQSNAoGd2luZG93GAIgASgLMiQua3VzaW50YS5pb3QuY29tbW9uLnYxLlBhaXJpbmdXaW5kb3cSOgoQaW5pdGlhbF9zcGFjZV9pZBgDIAEoCzIgLmt1c2ludGEuaW90LmlkZW50aXR5LnYxLlNwYWNlSWQSPQoJb3duZXJzaGlwGAQgASgOMioua3VzaW50YS5pb3QuY29tbW9uLnYxLkRldmljZU93bmVyc2hpcFR5cGUijwEKDlBhaXJpbmdTdGFydGVkEhMKC2luX3JlcGx5X3RvGAEgASgJEi4KCmV4cGlyZXNfYXQYAiABKAsyGi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wEjgKBWVycm9yGAMgASgLMikua3VzaW50YS5pb3QuY29tbW9uLnYxLlBhaXJpbmdFcnJvckRldGFpbCKXAQoPUGFpcmluZ0ZpbmlzaGVkEhMKC2luX3JlcGx5X3RvGAEgASgJEjUKCmRldmljZV9pZHMYAiADKAsyIS5rdXNpbnRhLmlvdC5pZGVudGl0eS52MS5EZXZpY2VJZBI4CgVlcnJvchgDIAEoCzIpLmt1c2ludGEuaW90LmNvbW1vbi52MS5QYWlyaW5nRXJyb3JEZXRhaWwiTQoLTGlua0NoYW5nZWQSLQoEbGluaxgBIAEoCzIfLmt1c2ludGEuaW90LmxpbmsudjEuRGV2aWNlTGluaxIPCgdyZW1vdmVkGAIgASgIItcICg5HYXRld2F5TWVzc2FnZRISCgptZXNzYWdlX2lkGAEgASgJEisKB3NlbnRfYXQYAiABKAsyGi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wEkQKDnN0YXRlX3NuYXBzaG90GAMgASgLMioua3VzaW50YS5pb3Qud2VicnRjLnYxLkRldmljZVN0YXRlU25hcHNob3RIABJACg9wcm9wZXJ0eV9yZXBvcnQYBCABKAsyJS5rdXNpbnRhLmlvdC53ZWJydGMudjEuUHJvcGVydHlSZXBvcnRIABJIChFwZXJtaXNzaW9uX3VwZGF0ZRgFIAEoCzIrLmt1c2ludGEuaW90LndlYnJ0Yy52MS5MaXZlUGVybWlzc2lvblVwZGF0ZUgAEj4KDmNvbW1hbmRfcmVzdWx0GAYgASgLMiQua3VzaW50YS5pb3Qud2VicnRjLnYxLkNvbW1hbmRSZXN1bHRIABIrCgRwb25nGAggASgLMhsua3VzaW50YS5pb3Qud2VicnRjLnYxLlBvbmdIABJGChJoYW5kc2hha2VfcmVqZWN0ZWQYCSABKAsyKC5rdXNpbnRhLmlvdC53ZWJydGMudjEuSGFuZHNoYWtlUmVqZWN0ZWRIABI0CgVlcnJvchgKIAEoCzIjLmt1c2ludGEuaW90LndlYnJ0Yy52MS5HYXRld2F5RXJyb3JIABJCChBzdWJzY3JpcHRpb25fYWNrGAsgASgLMiYua3VzaW50YS5pb3Qud2VicnRjLnYxLlN1YnNjcmlwdGlvbkFja0gAEjoKDGRldmljZV9hZGRlZBgMIAEoCzIiLmt1c2ludGEuaW90LndlYnJ0Yy52MS5EZXZpY2VBZGRlZEgAEj4KDmRldmljZV9yZW1vdmVkGA0gASgLMiQua3VzaW50YS5pb3Qud2VicnRjLnYxLkRldmljZVJlbW92ZWRIABJEChFtYW5hZ2VtZW50X3Jlc3VsdBgOIAEoCzInLmt1c2ludGEuaW90LndlYnJ0Yy52MS5NYW5hZ2VtZW50UmVzdWx0SAASQAoNZGV2aWNlX2V2ZW50cxgQIAEoCzInLmt1c2ludGEuaW90LmRldmljZS52MS5EZXZpY2VFdmVudEJhdGNoSAASQAoPcGFpcmluZ19zdGFydGVkGBEgASgLMiUua3VzaW50YS5pb3Qud2VicnRjLnYxLlBhaXJpbmdTdGFydGVkSAASQgoQcGFpcmluZ19maW5pc2hlZBgSIAEoCzImLmt1c2ludGEuaW90LndlYnJ0Yy52MS5QYWlyaW5nRmluaXNoZWRIABI6CgxsaW5rX2NoYW5nZWQYEyABKAsyIi5rdXNpbnRhLmlvdC53ZWJydGMudjEuTGlua0NoYW5nZWRIAEIJCgdwYXlsb2FkSgQIDxAQSgQIBxAIUhZhdHRyaWJ1dGVfd3JpdGVfcmVzdWx0Ug5wcm9wZXJ0eV9ldmVudCKDBQoKQXBwTWVzc2FnZRISCgptZXNzYWdlX2lkGAEgASgJEisKB3NlbnRfYXQYAiABKAsyGi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wEjgKCWhhbmRzaGFrZRgDIAEoCzIjLmt1c2ludGEuaW90LndlYnJ0Yy52MS5BcHBIYW5kc2hha2VIABI3Cgdjb21tYW5kGAQgASgLMiQua3VzaW50YS5pb3Qud2VicnRjLnYxLkRldmljZUNvbW1hbmRIABJCCgxyZWFkX3JlcXVlc3QYBSABKAsyKi5rdXNpbnRhLmlvdC53ZWJydGMudjEuUHJvcGVydHlSZWFkUmVxdWVzdEgAEisKBHBpbmcYBiABKAsyGy5rdXNpbnRhLmlvdC53ZWJydGMudjEuUGluZ0gAEjwKCXN1YnNjcmliZRgHIAEoCzInLmt1c2ludGEuaW90LndlYnJ0Yy52MS5TdWJzY3JpYmVEZXZpY2VzSAASQAoLdW5zdWJzY3JpYmUYCCABKAsyKS5rdXNpbnRhLmlvdC53ZWJydGMudjEuVW5zdWJzY3JpYmVEZXZpY2VzSAASPgoKbWFuYWdlbWVudBgJIAEoCzIoLmt1c2ludGEuaW90LndlYnJ0Yy52MS5NYW5hZ2VtZW50UmVxdWVzdEgAEkcKD2F0dHJpYnV0ZV93cml0ZRgKIAEoCzIsLmt1c2ludGEuaW90LndlYnJ0Yy52MS5BdHRyaWJ1dGVXcml0ZVJlcXVlc3RIABI8Cg1zdGFydF9wYWlyaW5nGAsgASgLMiMua3VzaW50YS5pb3Qud2VicnRjLnYxLlN0YXJ0UGFpcmluZ0gAQgkKB3BheWxvYWQq9gEKEEdhdGV3YXlFcnJvckNvZGUSIgoeR0FURVdBWV9FUlJPUl9DT0RFX1VOU1BFQ0lGSUVEEAASIwofR0FURVdBWV9FUlJPUl9DT0RFX05PVF9FTlRJVExFRBABEiYKIkdBVEVXQVlfRVJST1JfQ09ERV9JTlZBTElEX1JFUVVFU1QQAhIiCh5HQVRFV0FZX0VSUk9SX0NPREVfVU5BVkFJTEFCTEUQAxIfChtHQVRFV0FZX0VSUk9SX0NPREVfSU5URVJOQUwQBBIsCihHQVRFV0FZX0VSUk9SX0NPREVfU0VTU0lPTl9MSU1JVF9SRUFDSEVEEAVCAkgBYgZwcm90bzM", [file_google_protobuf_timestamp, file_kusinta_iot_access_v1_acl, file_kusinta_iot_common_v1_pairing, file_kusinta_iot_common_v1_types, file_kusinta_iot_device_v1_device_event, file_kusinta_iot_identity_v1_identity, file_kusinta_iot_link_v1_link, file_kusinta_iot_space_v1_space, file_kusinta_iot_webrtc_v1_command, file_kusinta_iot_webrtc_v1_device_state, file_kusinta_iot_webrtc_v1_management, file_kusinta_iot_webrtc_v1_permission_push]);
23
24
 
24
25
  /**
25
26
  * Describes the message kusinta.iot.webrtc.v1.Ping.
@@ -119,19 +120,26 @@ export const PairingStartedSchema = /*@__PURE__*/
119
120
  export const PairingFinishedSchema = /*@__PURE__*/
120
121
  messageDesc(file_kusinta_iot_webrtc_v1_envelope, 13);
121
122
 
123
+ /**
124
+ * Describes the message kusinta.iot.webrtc.v1.LinkChanged.
125
+ * Use `create(LinkChangedSchema)` to create a new message.
126
+ */
127
+ export const LinkChangedSchema = /*@__PURE__*/
128
+ messageDesc(file_kusinta_iot_webrtc_v1_envelope, 14);
129
+
122
130
  /**
123
131
  * Describes the message kusinta.iot.webrtc.v1.GatewayMessage.
124
132
  * Use `create(GatewayMessageSchema)` to create a new message.
125
133
  */
126
134
  export const GatewayMessageSchema = /*@__PURE__*/
127
- messageDesc(file_kusinta_iot_webrtc_v1_envelope, 14);
135
+ messageDesc(file_kusinta_iot_webrtc_v1_envelope, 15);
128
136
 
129
137
  /**
130
138
  * Describes the message kusinta.iot.webrtc.v1.AppMessage.
131
139
  * Use `create(AppMessageSchema)` to create a new message.
132
140
  */
133
141
  export const AppMessageSchema = /*@__PURE__*/
134
- messageDesc(file_kusinta_iot_webrtc_v1_envelope, 15);
142
+ messageDesc(file_kusinta_iot_webrtc_v1_envelope, 16);
135
143
 
136
144
  /**
137
145
  * Describes the enum kusinta.iot.webrtc.v1.GatewayErrorCode.