@kusinta/iot-schema 0.1.0-beta.9 → 0.2.0-beta.10

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.
Files changed (53) hide show
  1. package/package.json +19 -2
  2. package/src/kusinta/iot/access/v1/acl_pb.d.ts +230 -11
  3. package/src/kusinta/iot/access/v1/acl_pb.js +26 -5
  4. package/src/kusinta/iot/access/v1/roles_pb.d.ts +95 -2
  5. package/src/kusinta/iot/access/v1/roles_pb.js +37 -1
  6. package/src/kusinta/iot/common/v1/pairing_pb.d.ts +201 -0
  7. package/src/kusinta/iot/common/v1/pairing_pb.js +50 -0
  8. package/src/kusinta/iot/connector/v1/connector_pb.d.ts +481 -34
  9. package/src/kusinta/iot/connector/v1/connector_pb.js +81 -22
  10. package/src/kusinta/iot/connector/v1/connector_service_pb.d.ts +5 -5
  11. package/src/kusinta/iot/connector/v1/connector_service_pb.js +1 -1
  12. package/src/kusinta/iot/device/v1/cluster_state_pb.d.ts +263 -0
  13. package/src/kusinta/iot/device/v1/cluster_state_pb.js +54 -0
  14. package/src/kusinta/iot/device/v1/descriptor_pb.d.ts +53 -9
  15. package/src/kusinta/iot/device/v1/descriptor_pb.js +3 -1
  16. package/src/kusinta/iot/device/v1/device_event_pb.d.ts +162 -0
  17. package/src/kusinta/iot/device/v1/device_event_pb.js +45 -0
  18. package/src/kusinta/iot/device/v1/device_pb.d.ts +185 -28
  19. package/src/kusinta/iot/device/v1/device_pb.js +10 -2
  20. package/src/kusinta/iot/device/v1/matter_options_pb.d.ts +110 -0
  21. package/src/kusinta/iot/device/v1/matter_options_pb.js +118 -0
  22. package/src/kusinta/iot/device/v1/properties_pb.d.ts +240 -205
  23. package/src/kusinta/iot/device/v1/properties_pb.js +9 -1
  24. package/src/kusinta/iot/device/v1/property_update_pb.d.ts +197 -8
  25. package/src/kusinta/iot/device/v1/property_update_pb.js +20 -2
  26. package/src/kusinta/iot/link/v1/link_pb.d.ts +419 -0
  27. package/src/kusinta/iot/link/v1/link_pb.js +121 -0
  28. package/src/kusinta/iot/registration/v1/registration_pb.d.ts +170 -0
  29. package/src/kusinta/iot/registration/v1/registration_pb.js +61 -0
  30. package/src/kusinta/iot/registration/v1/registration_service_pb.d.ts +34 -0
  31. package/src/kusinta/iot/registration/v1/registration_service_pb.js +19 -0
  32. package/src/kusinta/iot/signaling/v1/signaling_pb.d.ts +320 -0
  33. package/src/kusinta/iot/signaling/v1/signaling_pb.js +83 -0
  34. package/src/kusinta/iot/signaling/v1/signaling_service_pb.d.ts +34 -0
  35. package/src/kusinta/iot/signaling/v1/signaling_service_pb.js +19 -0
  36. package/src/kusinta/iot/vendor/homematic/v1/homematic_pb.d.ts +202 -35
  37. package/src/kusinta/iot/vendor/homematic/v1/homematic_pb.js +14 -6
  38. package/src/kusinta/iot/vendor/v1/vendor_options_pb.d.ts +71 -0
  39. package/src/kusinta/iot/vendor/v1/vendor_options_pb.js +75 -0
  40. package/src/kusinta/iot/webrtc/v1/app_token_pb.d.ts +152 -0
  41. package/src/kusinta/iot/webrtc/v1/app_token_pb.js +28 -0
  42. package/src/kusinta/iot/webrtc/v1/command_pb.d.ts +277 -39
  43. package/src/kusinta/iot/webrtc/v1/command_pb.js +29 -2
  44. package/src/kusinta/iot/webrtc/v1/device_state_pb.d.ts +76 -7
  45. package/src/kusinta/iot/webrtc/v1/device_state_pb.js +20 -5
  46. package/src/kusinta/iot/webrtc/v1/envelope_pb.d.ts +603 -25
  47. package/src/kusinta/iot/webrtc/v1/envelope_pb.js +99 -5
  48. package/src/kusinta/iot/webrtc/v1/management_pb.d.ts +627 -0
  49. package/src/kusinta/iot/webrtc/v1/management_pb.js +135 -0
  50. package/src/kusinta/iot/webrtc/v1/permission_push_pb.d.ts +7 -1
  51. package/src/kusinta/iot/webrtc/v1/permission_push_pb.js +2 -2
  52. package/src/kusinta/iot/webrtc/v1/setpoint_mode_pb.d.ts +63 -0
  53. package/src/kusinta/iot/webrtc/v1/setpoint_mode_pb.js +45 -0
@@ -2,13 +2,20 @@
2
2
  // @generated from file kusinta/iot/webrtc/v1/envelope.proto (package kusinta.iot.webrtc.v1, syntax proto3)
3
3
  /* eslint-disable */
4
4
 
5
- import type { GenFile, GenMessage } from "@bufbuild/protobuf/codegenv2";
5
+ import type { GenEnum, GenFile, GenMessage } from "@bufbuild/protobuf/codegenv2";
6
6
  import type { Message } from "@bufbuild/protobuf";
7
- import type { DeviceId } from "../../identity/v1/identity_pb.js";
7
+ import type { ConnectorId, DeviceId, SpaceId } from "../../identity/v1/identity_pb.js";
8
+ import type { AttributeRef } from "../../access/v1/acl_pb.js";
9
+ import type { Space } from "../../space/v1/space_pb.js";
10
+ import type { ManagementAck, ManagementRequest, SpaceTree } from "./management_pb.js";
11
+ import type { DeviceLink, DeviceLinkList } from "../../link/v1/link_pb.js";
12
+ import type { PairingErrorDetail, PairingWindow } from "../../common/v1/pairing_pb.js";
13
+ import type { DeviceOwnershipType } from "../../common/v1/types_pb.js";
8
14
  import type { Timestamp } from "@bufbuild/protobuf/wkt";
9
- import type { DevicePropertyEvent, DeviceStateSnapshot } from "./device_state_pb.js";
15
+ import type { DeviceAdded, DeviceRemoved, DeviceStateSnapshot, PropertyReport } from "./device_state_pb.js";
10
16
  import type { LivePermissionUpdate } from "./permission_push_pb.js";
11
- import type { CommandResult, DeviceCommand } from "./command_pb.js";
17
+ import type { AttributeWriteRequest, CommandResult, DeviceCommand } from "./command_pb.js";
18
+ import type { DeviceEventBatch } from "../../device/v1/device_event_pb.js";
12
19
 
13
20
  /**
14
21
  * Describes the file kusinta/iot/webrtc/v1/envelope.proto.
@@ -56,19 +63,29 @@ export declare type HandshakeRejected = Message<"kusinta.iot.webrtc.v1.Handshake
56
63
  export declare const HandshakeRejectedSchema: GenMessage<HandshakeRejected>;
57
64
 
58
65
  /**
59
- * AppHandshake must be the first message sent by the Flutter app on the data channel.
60
- * The gateway validates the JWT locally using the mykusinta-api-server public key,
66
+ * AppHandshake must be the first message sent by the app on the data channel.
67
+ * The gateway validates the JWT locally using the api-server's public key,
61
68
  * checks that gateway_id in the JWT matches this gateway, then extracts the role.
62
69
  *
63
70
  * @generated from message kusinta.iot.webrtc.v1.AppHandshake
64
71
  */
65
72
  export declare type AppHandshake = Message<"kusinta.iot.webrtc.v1.AppHandshake"> & {
66
73
  /**
74
+ * Signed compact JWS. Its payload claims are documented by AppTokenClaims
75
+ * in app_token.proto — the shared contract between the api-server (issuer)
76
+ * and the gateway (validator).
77
+ *
67
78
  * @generated from field: string jwt = 1;
68
79
  */
69
80
  jwt: string;
70
81
 
71
82
  /**
83
+ * Initial interest set — an optimisation that saves one round trip, equivalent to
84
+ * sending SubscribeDevices immediately after the handshake. Interest only: naming
85
+ * an id here does not entitle the app to it, and ids the user may not see are
86
+ * refused in the SubscriptionAck that follows. Not the only mechanism — the set is
87
+ * revisable mid-session via AppMessage.subscribe / .unsubscribe.
88
+ *
72
89
  * @generated from field: repeated kusinta.iot.identity.v1.DeviceId subscribe_device_ids = 2;
73
90
  */
74
91
  subscribeDeviceIds: DeviceId[];
@@ -81,23 +98,129 @@ export declare type AppHandshake = Message<"kusinta.iot.webrtc.v1.AppHandshake">
81
98
  export declare const AppHandshakeSchema: GenMessage<AppHandshake>;
82
99
 
83
100
  /**
84
- * @generated from message kusinta.iot.webrtc.v1.PropertyReadRequest
101
+ * Adds device_ids to what the app wants streamed. Interest, never entitlement:
102
+ * the gateway intersects the request with what the user is permitted to see and
103
+ * reports what it declined in SubscriptionAck.refused. Additive — ids already in
104
+ * the set are a no-op, so a retry after a dropped ack is safe.
105
+ *
106
+ * @generated from message kusinta.iot.webrtc.v1.SubscribeDevices
85
107
  */
86
- export declare type PropertyReadRequest = Message<"kusinta.iot.webrtc.v1.PropertyReadRequest"> & {
108
+ export declare type SubscribeDevices = Message<"kusinta.iot.webrtc.v1.SubscribeDevices"> & {
109
+ /**
110
+ * @generated from field: repeated kusinta.iot.identity.v1.DeviceId device_ids = 1;
111
+ */
112
+ deviceIds: DeviceId[];
113
+ };
114
+
115
+ /**
116
+ * Describes the message kusinta.iot.webrtc.v1.SubscribeDevices.
117
+ * Use `create(SubscribeDevicesSchema)` to create a new message.
118
+ */
119
+ export declare const SubscribeDevicesSchema: GenMessage<SubscribeDevices>;
120
+
121
+ /**
122
+ * Removes device_ids from what the app wants streamed. Removing an id the app is
123
+ * not subscribed to is a no-op, not an error.
124
+ *
125
+ * @generated from message kusinta.iot.webrtc.v1.UnsubscribeDevices
126
+ */
127
+ export declare type UnsubscribeDevices = Message<"kusinta.iot.webrtc.v1.UnsubscribeDevices"> & {
128
+ /**
129
+ * @generated from field: repeated kusinta.iot.identity.v1.DeviceId device_ids = 1;
130
+ */
131
+ deviceIds: DeviceId[];
132
+ };
133
+
134
+ /**
135
+ * Describes the message kusinta.iot.webrtc.v1.UnsubscribeDevices.
136
+ * Use `create(UnsubscribeDevicesSchema)` to create a new message.
137
+ */
138
+ export declare const UnsubscribeDevicesSchema: GenMessage<UnsubscribeDevices>;
139
+
140
+ /**
141
+ * A device the gateway declined to add to the interest set. Ids the gateway does
142
+ * not know are refused as NOT_ENTITLED rather than a distinct not-found code, so
143
+ * the ack cannot be used to enumerate devices the user may not see.
144
+ *
145
+ * @generated from message kusinta.iot.webrtc.v1.RefusedSubscription
146
+ */
147
+ export declare type RefusedSubscription = Message<"kusinta.iot.webrtc.v1.RefusedSubscription"> & {
87
148
  /**
88
149
  * @generated from field: kusinta.iot.identity.v1.DeviceId device_id = 1;
89
150
  */
90
151
  deviceId?: DeviceId | undefined;
91
152
 
92
153
  /**
93
- * @generated from field: string attribute_name = 2;
154
+ * @generated from field: kusinta.iot.webrtc.v1.GatewayErrorCode code = 2;
94
155
  */
95
- attributeName: string;
156
+ code: GatewayErrorCode;
96
157
 
97
158
  /**
98
- * @generated from field: string cluster_id_hex = 3;
159
+ * human-readable, for logs
160
+ *
161
+ * @generated from field: string message = 3;
99
162
  */
100
- clusterIdHex: string;
163
+ message: string;
164
+ };
165
+
166
+ /**
167
+ * Describes the message kusinta.iot.webrtc.v1.RefusedSubscription.
168
+ * Use `create(RefusedSubscriptionSchema)` to create a new message.
169
+ */
170
+ export declare const RefusedSubscriptionSchema: GenMessage<RefusedSubscription>;
171
+
172
+ /**
173
+ * Answer to SubscribeDevices / UnsubscribeDevices, gateway → app.
174
+ * `subscribed` is the effective set after the change, not a delta: an app that
175
+ * missed an ack or raced two requests re-syncs from it without reconnecting.
176
+ *
177
+ * @generated from message kusinta.iot.webrtc.v1.SubscriptionAck
178
+ */
179
+ export declare type SubscriptionAck = Message<"kusinta.iot.webrtc.v1.SubscriptionAck"> & {
180
+ /**
181
+ * AppMessage.message_id of the request
182
+ *
183
+ * @generated from field: string in_reply_to = 1;
184
+ */
185
+ inReplyTo: string;
186
+
187
+ /**
188
+ * @generated from field: repeated kusinta.iot.identity.v1.DeviceId subscribed = 2;
189
+ */
190
+ subscribed: DeviceId[];
191
+
192
+ /**
193
+ * @generated from field: repeated kusinta.iot.webrtc.v1.RefusedSubscription refused = 3;
194
+ */
195
+ refused: RefusedSubscription[];
196
+ };
197
+
198
+ /**
199
+ * Describes the message kusinta.iot.webrtc.v1.SubscriptionAck.
200
+ * Use `create(SubscriptionAckSchema)` to create a new message.
201
+ */
202
+ export declare const SubscriptionAckSchema: GenMessage<SubscriptionAck>;
203
+
204
+ /**
205
+ * Reads one attribute of one endpoint, on demand. The carrier for
206
+ * PERMISSION_ACTION_READ.
207
+ *
208
+ * Addressed by AttributeRef, the same type a write, a grant and a constraint use — so a
209
+ * read, the write that changes the value, and the permission covering both name the
210
+ * attribute identically.
211
+ *
212
+ * @generated from message kusinta.iot.webrtc.v1.PropertyReadRequest
213
+ */
214
+ export declare type PropertyReadRequest = Message<"kusinta.iot.webrtc.v1.PropertyReadRequest"> & {
215
+ /**
216
+ * @generated from field: kusinta.iot.identity.v1.DeviceId device_id = 1;
217
+ */
218
+ deviceId?: DeviceId | undefined;
219
+
220
+ /**
221
+ * @generated from field: kusinta.iot.access.v1.AttributeRef target = 7;
222
+ */
223
+ target?: AttributeRef | undefined;
101
224
  };
102
225
 
103
226
  /**
@@ -107,8 +230,311 @@ export declare type PropertyReadRequest = Message<"kusinta.iot.webrtc.v1.Propert
107
230
  export declare const PropertyReadRequestSchema: GenMessage<PropertyReadRequest>;
108
231
 
109
232
  /**
110
- * GatewayMessage: gateway → Flutter app
233
+ * Session-level error, gateway → app. Mirrors connector.v1.GatewayError
234
+ * on the connector leg; kept separate because the two legs have different
235
+ * authorization semantics and this one has a closed code vocabulary.
236
+ *
237
+ * @generated from message kusinta.iot.webrtc.v1.GatewayError
238
+ */
239
+ export declare type GatewayError = Message<"kusinta.iot.webrtc.v1.GatewayError"> & {
240
+ /**
241
+ * @generated from field: kusinta.iot.webrtc.v1.GatewayErrorCode code = 1;
242
+ */
243
+ code: GatewayErrorCode;
244
+
245
+ /**
246
+ * human-readable, for logs — never rendered to a user
247
+ *
248
+ * @generated from field: string message = 2;
249
+ */
250
+ message: string;
251
+
252
+ /**
253
+ * structured detail, e.g. {"device_id": "therm-1"}
254
+ *
255
+ * @generated from field: map<string, string> metadata = 3;
256
+ */
257
+ metadata: { [key: string]: string };
258
+ };
259
+
260
+ /**
261
+ * Describes the message kusinta.iot.webrtc.v1.GatewayError.
262
+ * Use `create(GatewayErrorSchema)` to create a new message.
263
+ */
264
+ export declare const GatewayErrorSchema: GenMessage<GatewayError>;
265
+
266
+ /**
267
+ * Answer to a ManagementRequest, gateway → app. Lives here rather than beside the
268
+ * requests in management.proto because it carries GatewayError, which is declared
269
+ * in this file; the other direction would be an import cycle.
111
270
  *
271
+ * Exactly one result arrives per request, correlated by in_reply_to. A refusal is
272
+ * an ordinary result, not a session-level error: a filing operation the caller may
273
+ * not perform says so and the session continues. Targets the caller cannot reach
274
+ * are refused as NOT_ENTITLED whether or not they exist, so no result here reveals
275
+ * which spaces or devices are out there.
276
+ *
277
+ * @generated from message kusinta.iot.webrtc.v1.ManagementResult
278
+ */
279
+ export declare type ManagementResult = Message<"kusinta.iot.webrtc.v1.ManagementResult"> & {
280
+ /**
281
+ * AppMessage.message_id of the request
282
+ *
283
+ * @generated from field: string in_reply_to = 1;
284
+ */
285
+ inReplyTo: string;
286
+
287
+ /**
288
+ * @generated from oneof kusinta.iot.webrtc.v1.ManagementResult.result
289
+ */
290
+ result: {
291
+ /**
292
+ * refused, or the request was malformed
293
+ *
294
+ * @generated from field: kusinta.iot.webrtc.v1.GatewayError error = 2;
295
+ */
296
+ value: GatewayError;
297
+ case: "error";
298
+ } | {
299
+ /**
300
+ * create_space, update_space
301
+ *
302
+ * @generated from field: kusinta.iot.space.v1.Space space = 3;
303
+ */
304
+ value: Space;
305
+ case: "space";
306
+ } | {
307
+ /**
308
+ * list_spaces
309
+ *
310
+ * @generated from field: kusinta.iot.webrtc.v1.SpaceTree space_tree = 4;
311
+ */
312
+ value: SpaceTree;
313
+ case: "spaceTree";
314
+ } | {
315
+ /**
316
+ * everything else
317
+ *
318
+ * @generated from field: kusinta.iot.webrtc.v1.ManagementAck ack = 5;
319
+ */
320
+ value: ManagementAck;
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";
330
+ } | { case: undefined; value?: undefined };
331
+ };
332
+
333
+ /**
334
+ * Describes the message kusinta.iot.webrtc.v1.ManagementResult.
335
+ * Use `create(ManagementResultSchema)` to create a new message.
336
+ */
337
+ export declare const ManagementResultSchema: GenMessage<ManagementResult>;
338
+
339
+ /**
340
+ * Asks the gateway to put a connector into pairing mode, so a device joined during the
341
+ * window becomes the caller's rather than belonging to nobody.
342
+ *
343
+ * A payload case of its own rather than a ManagementRequest. Those are gated on a target —
344
+ * a space, a device — and that is the justification for keeping them behind one wrapper.
345
+ * This one names no target: connector_id is optional, and unset means every connector, so
346
+ * it is authorized against the caller's role and nothing else.
347
+ *
348
+ * Answered twice, and the two answers say different things at different times.
349
+ * PairingStarted reports whether the window opened; PairingFinished reports what came of
350
+ * it, seconds or minutes later, once someone has pressed a button on hardware that may be
351
+ * asleep or out of range.
352
+ *
353
+ * @generated from message kusinta.iot.webrtc.v1.StartPairing
354
+ */
355
+ export declare type StartPairing = Message<"kusinta.iot.webrtc.v1.StartPairing"> & {
356
+ /**
357
+ * Which connector to open. Unset means every connector the gateway holds, which is the
358
+ * sensible default: a device picks its hub by radio range, and asking a user to choose is
359
+ * asking them to guess at something they cannot observe.
360
+ *
361
+ * Name one where the answer is not a guess — a device that will be linked to devices on a
362
+ * particular hub has to join that hub, because links are held by the hub that brokered
363
+ * them.
364
+ *
365
+ * @generated from field: kusinta.iot.identity.v1.ConnectorId connector_id = 1;
366
+ */
367
+ connectorId?: ConnectorId | undefined;
368
+
369
+ /**
370
+ * How long, which device, how many. See PairingWindow.
371
+ *
372
+ * @generated from field: kusinta.iot.common.v1.PairingWindow window = 2;
373
+ */
374
+ window?: PairingWindow | undefined;
375
+
376
+ /**
377
+ * Where to file the device once it arrives.
378
+ *
379
+ * Optional, and the two cases differ. A caller pairing a device of their own must name a
380
+ * space they reach, so it is theirs and placed on arrival rather than sitting unfiled and
381
+ * invisible to them. A caller commissioning for a building may leave it unset: a building
382
+ * is commissioned before its spaces are recorded, and an unfiled device is visible to the
383
+ * administrator, who is the person doing the pairing.
384
+ *
385
+ * @generated from field: kusinta.iot.identity.v1.SpaceId initial_space_id = 3;
386
+ */
387
+ initialSpaceId?: SpaceId | undefined;
388
+
389
+ /**
390
+ * What the device should become. Unset lets the gateway decide from the caller's role,
391
+ * which is the reading that scales: someone commissioning fifty devices for a building
392
+ * should not come to own fifty devices because a field defaulted.
393
+ *
394
+ * The gateway refuses an ownership the caller may not confer, and never mints ownership
395
+ * for a third party — handing a device to someone else is a transfer, a separate operation
396
+ * with its own authority.
397
+ *
398
+ * @generated from field: kusinta.iot.common.v1.DeviceOwnershipType ownership = 4;
399
+ */
400
+ ownership: DeviceOwnershipType;
401
+ };
402
+
403
+ /**
404
+ * Describes the message kusinta.iot.webrtc.v1.StartPairing.
405
+ * Use `create(StartPairingSchema)` to create a new message.
406
+ */
407
+ export declare const StartPairingSchema: GenMessage<StartPairing>;
408
+
409
+ /**
410
+ * Whether the pairing window opened, gateway → app. The first of two answers to a
411
+ * StartPairing.
412
+ *
413
+ * @generated from message kusinta.iot.webrtc.v1.PairingStarted
414
+ */
415
+ export declare type PairingStarted = Message<"kusinta.iot.webrtc.v1.PairingStarted"> & {
416
+ /**
417
+ * AppMessage.message_id of the StartPairing
418
+ *
419
+ * @generated from field: string in_reply_to = 1;
420
+ */
421
+ inReplyTo: string;
422
+
423
+ /**
424
+ * When the window closes. Present when it opened, and this is the value to count down
425
+ * from — not the duration that was asked for, which both the gateway and the connector
426
+ * clamp. A countdown run on the request rather than on this one disagrees with the hub.
427
+ *
428
+ * @generated from field: google.protobuf.Timestamp expires_at = 2;
429
+ */
430
+ expiresAt?: Timestamp | undefined;
431
+
432
+ /**
433
+ * Why it did not open. Present instead of expires_at.
434
+ *
435
+ * @generated from field: kusinta.iot.common.v1.PairingErrorDetail error = 3;
436
+ */
437
+ error?: PairingErrorDetail | undefined;
438
+ };
439
+
440
+ /**
441
+ * Describes the message kusinta.iot.webrtc.v1.PairingStarted.
442
+ * Use `create(PairingStartedSchema)` to create a new message.
443
+ */
444
+ export declare const PairingStartedSchema: GenMessage<PairingStarted>;
445
+
446
+ /**
447
+ * What the pairing window produced, gateway → app. The second and last answer, sent once
448
+ * when the window closes.
449
+ *
450
+ * One message per request, not per device: a batch window attributes several, and a client
451
+ * given one message each has nothing telling it the window is over and no defined moment to
452
+ * stop waiting. The devices are listed here; each also arrives as an ordinary DeviceAdded
453
+ * as it appears, so a client may show them as they come and use this to finish.
454
+ *
455
+ * An error and a non-empty device list are not exclusive. A batch of five that attributed
456
+ * three and then expired reports both — three devices and NO_DEVICE_APPEARED — because
457
+ * "some worked" and "the window ran out" are both true and a user needs to be told both.
458
+ *
459
+ * @generated from message kusinta.iot.webrtc.v1.PairingFinished
460
+ */
461
+ export declare type PairingFinished = Message<"kusinta.iot.webrtc.v1.PairingFinished"> & {
462
+ /**
463
+ * AppMessage.message_id of the StartPairing
464
+ *
465
+ * @generated from field: string in_reply_to = 1;
466
+ */
467
+ inReplyTo: string;
468
+
469
+ /**
470
+ * @generated from field: repeated kusinta.iot.identity.v1.DeviceId device_ids = 2;
471
+ */
472
+ deviceIds: DeviceId[];
473
+
474
+ /**
475
+ * Why the window produced fewer devices than asked for, absent when it produced them all.
476
+ * Note this is not always a failure of the request: a window that simply expired unused
477
+ * ends here too, and is the ordinary result of a user changing their mind.
478
+ *
479
+ * @generated from field: kusinta.iot.common.v1.PairingErrorDetail error = 3;
480
+ */
481
+ error?: PairingErrorDetail | undefined;
482
+ };
483
+
484
+ /**
485
+ * Describes the message kusinta.iot.webrtc.v1.PairingFinished.
486
+ * Use `create(PairingFinishedSchema)` to create a new message.
487
+ */
488
+ export declare const PairingFinishedSchema: GenMessage<PairingFinished>;
489
+
490
+ /**
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.
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
+ /**
112
538
  * @generated from message kusinta.iot.webrtc.v1.GatewayMessage
113
539
  */
114
540
  export declare type GatewayMessage = Message<"kusinta.iot.webrtc.v1.GatewayMessage"> & {
@@ -133,10 +559,10 @@ export declare type GatewayMessage = Message<"kusinta.iot.webrtc.v1.GatewayMessa
133
559
  case: "stateSnapshot";
134
560
  } | {
135
561
  /**
136
- * @generated from field: kusinta.iot.webrtc.v1.DevicePropertyEvent property_event = 4;
562
+ * @generated from field: kusinta.iot.webrtc.v1.PropertyReport property_report = 4;
137
563
  */
138
- value: DevicePropertyEvent;
139
- case: "propertyEvent";
564
+ value: PropertyReport;
565
+ case: "propertyReport";
140
566
  } | {
141
567
  /**
142
568
  * @generated from field: kusinta.iot.webrtc.v1.LivePermissionUpdate permission_update = 5;
@@ -149,14 +575,6 @@ export declare type GatewayMessage = Message<"kusinta.iot.webrtc.v1.GatewayMessa
149
575
  */
150
576
  value: CommandResult;
151
577
  case: "commandResult";
152
- } | {
153
- /**
154
- * error description string
155
- *
156
- * @generated from field: string error = 7;
157
- */
158
- value: string;
159
- case: "error";
160
578
  } | {
161
579
  /**
162
580
  * @generated from field: kusinta.iot.webrtc.v1.Pong pong = 8;
@@ -169,6 +587,65 @@ export declare type GatewayMessage = Message<"kusinta.iot.webrtc.v1.GatewayMessa
169
587
  */
170
588
  value: HandshakeRejected;
171
589
  case: "handshakeRejected";
590
+ } | {
591
+ /**
592
+ * @generated from field: kusinta.iot.webrtc.v1.GatewayError error = 10;
593
+ */
594
+ value: GatewayError;
595
+ case: "error";
596
+ } | {
597
+ /**
598
+ * @generated from field: kusinta.iot.webrtc.v1.SubscriptionAck subscription_ack = 11;
599
+ */
600
+ value: SubscriptionAck;
601
+ case: "subscriptionAck";
602
+ } | {
603
+ /**
604
+ * @generated from field: kusinta.iot.webrtc.v1.DeviceAdded device_added = 12;
605
+ */
606
+ value: DeviceAdded;
607
+ case: "deviceAdded";
608
+ } | {
609
+ /**
610
+ * @generated from field: kusinta.iot.webrtc.v1.DeviceRemoved device_removed = 13;
611
+ */
612
+ value: DeviceRemoved;
613
+ case: "deviceRemoved";
614
+ } | {
615
+ /**
616
+ * @generated from field: kusinta.iot.webrtc.v1.ManagementResult management_result = 14;
617
+ */
618
+ value: ManagementResult;
619
+ case: "managementResult";
620
+ } | {
621
+ /**
622
+ * 15 was attribute_write_result. Answers to attribute writes come back as
623
+ * command_result above instead: a write and an invoke differ in what they do to a
624
+ * device, not in how the gateway reports having done it, and request_id says which
625
+ * request is being answered either way.
626
+ *
627
+ * @generated from field: kusinta.iot.device.v1.DeviceEventBatch device_events = 16;
628
+ */
629
+ value: DeviceEventBatch;
630
+ case: "deviceEvents";
631
+ } | {
632
+ /**
633
+ * @generated from field: kusinta.iot.webrtc.v1.PairingStarted pairing_started = 17;
634
+ */
635
+ value: PairingStarted;
636
+ case: "pairingStarted";
637
+ } | {
638
+ /**
639
+ * @generated from field: kusinta.iot.webrtc.v1.PairingFinished pairing_finished = 18;
640
+ */
641
+ value: PairingFinished;
642
+ case: "pairingFinished";
643
+ } | {
644
+ /**
645
+ * @generated from field: kusinta.iot.webrtc.v1.LinkChanged link_changed = 19;
646
+ */
647
+ value: LinkChanged;
648
+ case: "linkChanged";
172
649
  } | { case: undefined; value?: undefined };
173
650
  };
174
651
 
@@ -179,7 +656,7 @@ export declare type GatewayMessage = Message<"kusinta.iot.webrtc.v1.GatewayMessa
179
656
  export declare const GatewayMessageSchema: GenMessage<GatewayMessage>;
180
657
 
181
658
  /**
182
- * AppMessage: Flutter app → gateway
659
+ * AppMessage: app → gateway
183
660
  *
184
661
  * @generated from message kusinta.iot.webrtc.v1.AppMessage
185
662
  */
@@ -221,6 +698,36 @@ export declare type AppMessage = Message<"kusinta.iot.webrtc.v1.AppMessage"> & {
221
698
  */
222
699
  value: Ping;
223
700
  case: "ping";
701
+ } | {
702
+ /**
703
+ * @generated from field: kusinta.iot.webrtc.v1.SubscribeDevices subscribe = 7;
704
+ */
705
+ value: SubscribeDevices;
706
+ case: "subscribe";
707
+ } | {
708
+ /**
709
+ * @generated from field: kusinta.iot.webrtc.v1.UnsubscribeDevices unsubscribe = 8;
710
+ */
711
+ value: UnsubscribeDevices;
712
+ case: "unsubscribe";
713
+ } | {
714
+ /**
715
+ * @generated from field: kusinta.iot.webrtc.v1.ManagementRequest management = 9;
716
+ */
717
+ value: ManagementRequest;
718
+ case: "management";
719
+ } | {
720
+ /**
721
+ * @generated from field: kusinta.iot.webrtc.v1.AttributeWriteRequest attribute_write = 10;
722
+ */
723
+ value: AttributeWriteRequest;
724
+ case: "attributeWrite";
725
+ } | {
726
+ /**
727
+ * @generated from field: kusinta.iot.webrtc.v1.StartPairing start_pairing = 11;
728
+ */
729
+ value: StartPairing;
730
+ case: "startPairing";
224
731
  } | { case: undefined; value?: undefined };
225
732
  };
226
733
 
@@ -230,3 +737,74 @@ export declare type AppMessage = Message<"kusinta.iot.webrtc.v1.AppMessage"> & {
230
737
  */
231
738
  export declare const AppMessageSchema: GenMessage<AppMessage>;
232
739
 
740
+ /**
741
+ * Machine-readable classification of a session-level gateway error, so the app
742
+ * can branch without string-matching a human sentence. Deliberately an enum here,
743
+ * unlike the free-form code on connector.v1.GatewayError: the app leg is versioned
744
+ * together with the gateway, and clients need an exhaustive switch.
745
+ *
746
+ * @generated from enum kusinta.iot.webrtc.v1.GatewayErrorCode
747
+ */
748
+ export enum GatewayErrorCode {
749
+ /**
750
+ * Sender did not set a code, or sent one this client's schema does not know.
751
+ *
752
+ * @generated from enum value: GATEWAY_ERROR_CODE_UNSPECIFIED = 0;
753
+ */
754
+ UNSPECIFIED = 0,
755
+
756
+ /**
757
+ * Permanent refusal — the user may not see or act on this. Stop asking, tell the user.
758
+ *
759
+ * @generated from enum value: GATEWAY_ERROR_CODE_NOT_ENTITLED = 1;
760
+ */
761
+ NOT_ENTITLED = 1,
762
+
763
+ /**
764
+ * The app sent something malformed. A client bug: log it, do not retry.
765
+ *
766
+ * @generated from enum value: GATEWAY_ERROR_CODE_INVALID_REQUEST = 2;
767
+ */
768
+ INVALID_REQUEST = 2,
769
+
770
+ /**
771
+ * Transient failure. Retrying is reasonable.
772
+ *
773
+ * @generated from enum value: GATEWAY_ERROR_CODE_UNAVAILABLE = 3;
774
+ */
775
+ UNAVAILABLE = 3,
776
+
777
+ /**
778
+ * Gateway-side fault. Not the app's doing; retry cautiously.
779
+ *
780
+ * @generated from enum value: GATEWAY_ERROR_CODE_INTERNAL = 4;
781
+ */
782
+ INTERNAL = 4,
783
+
784
+ /**
785
+ * The user already holds the maximum number of concurrent sessions this
786
+ * gateway will keep, and this attempt is refused. Permanent for this attempt:
787
+ * the limit does not clear on its own, so retrying is exactly the wrong
788
+ * response — the user must end another session first. Distinct from
789
+ * NOT_ENTITLED, which is a statement about what the user may see; this user
790
+ * may, they are simply already connected enough times.
791
+ *
792
+ * The limit itself is gateway configuration and deliberately not modelled
793
+ * here. GatewayError.message carries the specifics so a client can render
794
+ * something actionable.
795
+ *
796
+ * Rollout note: a client whose schema predates this value decodes it as
797
+ * UNSPECIFIED, which is retryable by design. Client handling must therefore
798
+ * ship before or with the gateway that emits it, and the gateway must close
799
+ * the session itself rather than rely on the client standing down.
800
+ *
801
+ * @generated from enum value: GATEWAY_ERROR_CODE_SESSION_LIMIT_REACHED = 5;
802
+ */
803
+ SESSION_LIMIT_REACHED = 5,
804
+ }
805
+
806
+ /**
807
+ * Describes the enum kusinta.iot.webrtc.v1.GatewayErrorCode.
808
+ */
809
+ export declare const GatewayErrorCodeSchema: GenEnum<GatewayErrorCode>;
810
+