@m1kad0/hannah-proto 5.1.0 → 5.3.0

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.
@@ -177,6 +177,7 @@ exports.REQUIRED_COMPAT_VERSIONS = {
177
177
  "/hannah.v2.HannahService/CreateMessage": 1,
178
178
  "/hannah.v2.HannahService/ListMessages": 1,
179
179
  "/hannah.v2.HannahService/DeleteMessage": 1,
180
+ "/hannah.v2.HannahService/Heartbeat": 1,
180
181
  "/hannah.v2.LogService/Ship": 1,
181
182
  "/hannah.v2.LogService/GetSources": 1,
182
183
  "/hannah.v2.LogService/Export": 1
Binary file
@@ -100,13 +100,15 @@ export interface CaptureControl {
100
100
  }
101
101
  /**
102
102
  * A state change event for a state Hannah asked to watch (AgentWatchMore), e.g. the
103
- * trigger engine's conditions. Devices are not reported this way, they use SlotUpdate.
103
+ * trigger engine's conditions. `state_id` is the identifier the adapter uses for the value
104
+ * (for ioBroker the state ID, the same as `Slot.identifier` for a slot of a device). Devices
105
+ * report their changes as SlotUpdate; a value that is both a slot and watched gets both.
104
106
  * ack=true means the device confirmed the value (as opposed to ack=false which is the
105
107
  * "desired" value). Hannah uses this to verify that a SetState command was executed
106
- * successfully.
108
+ * successfully. The value is the raw one of that state, not normalized to a slot scale.
107
109
  */
108
110
  export interface AgentStateUpdate {
109
- /** full ioBroker state ID, e.g. "0_userdata.0.feeded" */
111
+ /** identifier of the value, for ioBroker the full state ID, e.g. "0_userdata.0.feeded" */
110
112
  stateId: string;
111
113
  /** JSON-encoded value: "true", "42", "\"text\"" */
112
114
  value: string;
@@ -114,6 +116,13 @@ export interface AgentStateUpdate {
114
116
  ack: boolean;
115
117
  /** Unix timestamp in milliseconds */
116
118
  ts: bigint;
119
+ /**
120
+ * Field 5 is deliberately unused: in hannah.v1 it was `canonical_key`, a different type.
121
+ * true = the current value the adapter sends when it starts watching a state (its answer to
122
+ * AgentWatchMore), not a change. Hannah Core uses it to prefill the trigger engine's cache
123
+ * silently, without firing triggers: an update from "unknown" to a value is not a transition.
124
+ */
125
+ initial: boolean;
117
126
  }
118
127
  /** The text-command state in ioBroker changed — treat as a SubmitText call. */
119
128
  export interface AgentTextCommand {
@@ -183,15 +192,16 @@ export interface AgentFirmwareEvent {
183
192
  * confirms execution back to Hannah.
184
193
  */
185
194
  export interface AgentSetState {
186
- /** ioBroker state ID to write */
195
+ /** identifier of the value to write, for ioBroker the state ID */
187
196
  stateId: string;
188
197
  /** JSON-encoded value */
189
198
  value: string;
190
199
  }
191
200
  /**
192
- * Hannah requests additional state IDs to be included in the AgentStateUpdate stream.
193
- * Used by the trigger engine at runtime when triggers reference arbitrary state IDs
194
- * (e.g. unless.state: "0_userdata.0.feeded") that aren't covered by enum discovery.
201
+ * Hannah requests additional identifiers (for ioBroker state IDs) to be included in the
202
+ * AgentStateUpdate stream. Used by the trigger engine at runtime when triggers reference
203
+ * arbitrary values (e.g. unless.state: "0_userdata.0.feeded") that aren't covered by enum
204
+ * discovery. The adapter answers every new one with its current raw value, `initial` = true.
195
205
  */
196
206
  export interface AgentWatchMore {
197
207
  stateIds: string[];
package/dist/v2/agent.js CHANGED
@@ -476,7 +476,7 @@ exports.CaptureControl = {
476
476
  },
477
477
  };
478
478
  function createBaseAgentStateUpdate() {
479
- return { stateId: "", value: "", ack: false, ts: 0n };
479
+ return { stateId: "", value: "", ack: false, ts: 0n, initial: false };
480
480
  }
481
481
  exports.AgentStateUpdate = {
482
482
  encode(message, writer = new wire_1.BinaryWriter()) {
@@ -495,6 +495,9 @@ exports.AgentStateUpdate = {
495
495
  }
496
496
  writer.uint32(32).int64(message.ts);
497
497
  }
498
+ if (message.initial !== false) {
499
+ writer.uint32(48).bool(message.initial);
500
+ }
498
501
  return writer;
499
502
  },
500
503
  decode(input, length) {
@@ -538,6 +541,13 @@ exports.AgentStateUpdate = {
538
541
  message.ts = reader.int64();
539
542
  continue;
540
543
  }
544
+ case 6: {
545
+ if (tag !== 48) {
546
+ break;
547
+ }
548
+ message.initial = reader.bool();
549
+ continue;
550
+ }
541
551
  }
542
552
  if ((tag & 7) === 4 || tag === 0) {
543
553
  break;
@@ -559,6 +569,7 @@ exports.AgentStateUpdate = {
559
569
  message.value = object.value ?? "";
560
570
  message.ack = object.ack ?? false;
561
571
  message.ts = (object.ts !== undefined && object.ts !== null) ? BigInt(object.ts) : 0n;
572
+ message.initial = object.initial ?? false;
562
573
  return message;
563
574
  },
564
575
  };
@@ -163,6 +163,14 @@ export interface Slot {
163
163
  * honestly when a device cannot do what was asked.
164
164
  */
165
165
  options: string[];
166
+ /**
167
+ * How a trigger (and any client building triggers) refers to the value behind this slot: the
168
+ * identifier the adapter uses for it, for ioBroker the state ID. Opaque to Hannah Core, which
169
+ * only passes it through (AgentWatchMore, AgentSetState, AgentStateUpdate, trigger conditions
170
+ * and actions). Empty = not addressable by triggers. Triggers compare against the raw value
171
+ * of the identified state (and its own scale), not against the normalized `value` above.
172
+ */
173
+ identifier: string;
166
174
  }
167
175
  /** A device, as the adapter derived it from the ioBroker objects (grouping, class, slots). */
168
176
  export interface TypedDevice {
@@ -230,6 +230,7 @@ function createBaseSlot() {
230
230
  label: "",
231
231
  requiredTrustLevel: undefined,
232
232
  options: [],
233
+ identifier: "",
233
234
  };
234
235
  }
235
236
  exports.Slot = {
@@ -258,6 +259,9 @@ exports.Slot = {
258
259
  for (const v of message.options) {
259
260
  writer.uint32(66).string(v);
260
261
  }
262
+ if (message.identifier !== "") {
263
+ writer.uint32(74).string(message.identifier);
264
+ }
261
265
  return writer;
262
266
  },
263
267
  decode(input, length) {
@@ -329,6 +333,13 @@ exports.Slot = {
329
333
  message.options.push(reader.string());
330
334
  continue;
331
335
  }
336
+ case 9: {
337
+ if (tag !== 74) {
338
+ break;
339
+ }
340
+ message.identifier = reader.string();
341
+ continue;
342
+ }
332
343
  }
333
344
  if ((tag & 7) === 4 || tag === 0) {
334
345
  break;
@@ -356,6 +367,7 @@ exports.Slot = {
356
367
  message.label = object.label ?? "";
357
368
  message.requiredTrustLevel = object.requiredTrustLevel ?? undefined;
358
369
  message.options = object.options?.map((e) => e) || [];
370
+ message.identifier = object.identifier ?? "";
359
371
  return message;
360
372
  },
361
373
  };
@@ -1,3 +1,4 @@
1
+ import { BinaryReader, BinaryWriter } from "@bufbuild/protobuf/wire";
1
2
  import { type CallOptions, type ChannelCredentials, Client, type ClientDuplexStream, type ClientOptions, type ClientReadableStream, type ClientUnaryCall, type handleBidiStreamingCall, type handleServerStreamingCall, type handleUnaryCall, type Metadata, type ServiceError, type UntypedServiceImplementation } from "@grpc/grpc-js";
2
3
  import { ActivityAudioChunk, ListActivityLogRequest, ListActivityLogResponse, StreamActivityAudioRequest } from "./activity_log";
3
4
  import { AgentCommand, AgentMessage, AgentNotification } from "./agent";
@@ -19,6 +20,12 @@ import { TimerCommand, TimerMessage } from "./timer_service";
19
20
  import { CreateLinkTokenRequest, CreateLinkTokenResponse, CreateUserRequest, CreateUserResponse, DeleteUserRequest, GetResidentsResponse, GetUserRequest, GetUsersRequest, GetUsersResponse, LinkAccountRequest, LoginRequest, SetAutomationRequest, SetSystemMessagesRequest, SetTrustLevelRequest, UnlinkAccountRequest, UpdateUserRequest, UserResponse } from "./user_registry";
20
21
  import { CaptureCommand, CollectorMessage, SatelliteAudioChunk, SatelliteCaptureRequest, SatelliteCaptureResponse, TriggerPlinkRequest } from "./wakeword_capture";
21
22
  export declare const protobufPackage = "hannah.v2";
23
+ export interface HeartbeatRequest {
24
+ }
25
+ export interface HeartbeatResponse {
26
+ }
27
+ export declare const HeartbeatRequest: MessageFns<HeartbeatRequest>;
28
+ export declare const HeartbeatResponse: MessageFns<HeartbeatResponse>;
22
29
  export type HannahServiceService = typeof HannahServiceService;
23
30
  export declare const HannahServiceService: {
24
31
  /** --- User Registry --- */
@@ -956,6 +963,19 @@ export declare const HannahServiceService: {
956
963
  readonly responseSerialize: (value: StatusResponse) => Buffer;
957
964
  readonly responseDeserialize: (value: Buffer) => StatusResponse;
958
965
  };
966
+ /**
967
+ * Liveness signal from a component. The component names itself in the call metadata
968
+ * (x-component, x-component-version, x-component-id), the message carries nothing yet.
969
+ */
970
+ readonly heartbeat: {
971
+ readonly path: "/hannah.v2.HannahService/Heartbeat";
972
+ readonly requestStream: false;
973
+ readonly responseStream: false;
974
+ readonly requestSerialize: (value: HeartbeatRequest) => Buffer;
975
+ readonly requestDeserialize: (value: Buffer) => HeartbeatRequest;
976
+ readonly responseSerialize: (value: HeartbeatResponse) => Buffer;
977
+ readonly responseDeserialize: (value: Buffer) => HeartbeatResponse;
978
+ };
959
979
  };
960
980
  export interface HannahServiceServer extends UntypedServiceImplementation {
961
981
  /** --- User Registry --- */
@@ -1213,6 +1233,11 @@ export interface HannahServiceServer extends UntypedServiceImplementation {
1213
1233
  createMessage: handleUnaryCall<CreateMessageRequest, StatusResponse>;
1214
1234
  listMessages: handleUnaryCall<ListMessagesRequest, ListMessagesResponse>;
1215
1235
  deleteMessage: handleUnaryCall<DeleteMessageRequest, StatusResponse>;
1236
+ /**
1237
+ * Liveness signal from a component. The component names itself in the call metadata
1238
+ * (x-component, x-component-version, x-component-id), the message carries nothing yet.
1239
+ */
1240
+ heartbeat: handleUnaryCall<HeartbeatRequest, HeartbeatResponse>;
1216
1241
  }
1217
1242
  export interface HannahServiceClient extends Client {
1218
1243
  /** --- User Registry --- */
@@ -1636,9 +1661,33 @@ export interface HannahServiceClient extends Client {
1636
1661
  deleteMessage(request: DeleteMessageRequest, callback: (error: ServiceError | null, response: StatusResponse) => void): ClientUnaryCall;
1637
1662
  deleteMessage(request: DeleteMessageRequest, metadata: Metadata, callback: (error: ServiceError | null, response: StatusResponse) => void): ClientUnaryCall;
1638
1663
  deleteMessage(request: DeleteMessageRequest, metadata: Metadata, options: Partial<CallOptions>, callback: (error: ServiceError | null, response: StatusResponse) => void): ClientUnaryCall;
1664
+ /**
1665
+ * Liveness signal from a component. The component names itself in the call metadata
1666
+ * (x-component, x-component-version, x-component-id), the message carries nothing yet.
1667
+ */
1668
+ heartbeat(request: HeartbeatRequest, callback: (error: ServiceError | null, response: HeartbeatResponse) => void): ClientUnaryCall;
1669
+ heartbeat(request: HeartbeatRequest, metadata: Metadata, callback: (error: ServiceError | null, response: HeartbeatResponse) => void): ClientUnaryCall;
1670
+ heartbeat(request: HeartbeatRequest, metadata: Metadata, options: Partial<CallOptions>, callback: (error: ServiceError | null, response: HeartbeatResponse) => void): ClientUnaryCall;
1639
1671
  }
1640
1672
  export declare const HannahServiceClient: {
1641
1673
  new (address: string, credentials: ChannelCredentials, options?: Partial<ClientOptions>): HannahServiceClient;
1642
1674
  service: typeof HannahServiceService;
1643
1675
  serviceName: string;
1644
1676
  };
1677
+ type Builtin = Date | Function | Uint8Array | string | number | boolean | bigint | undefined;
1678
+ export type DeepPartial<T> = T extends bigint ? string | number | bigint : T extends Builtin ? T : T extends globalThis.Array<infer U> ? globalThis.Array<DeepPartial<U>> : T extends ReadonlyArray<infer U> ? ReadonlyArray<DeepPartial<U>> : T extends {} ? {
1679
+ [K in keyof T]?: DeepPartial<T[K]>;
1680
+ } : Partial<T>;
1681
+ type KeysOfUnion<T> = T extends T ? keyof T : never;
1682
+ export type Exact<P, I extends P> = P extends Builtin ? P : P & {
1683
+ [K in keyof P]: Exact<P[K], I[K]>;
1684
+ } & {
1685
+ [K in Exclude<keyof I, KeysOfUnion<P>>]: never;
1686
+ };
1687
+ export interface MessageFns<T> {
1688
+ encode(message: T, writer?: BinaryWriter): BinaryWriter;
1689
+ decode(input: BinaryReader | Uint8Array, length?: number): T;
1690
+ create<I extends Exact<DeepPartial<T>, I>>(base?: I): T;
1691
+ fromPartial<I extends Exact<DeepPartial<T>, I>>(object: I): T;
1692
+ }
1693
+ export {};
package/dist/v2/hannah.js CHANGED
@@ -5,8 +5,9 @@
5
5
  // protoc unknown
6
6
  // source: hannah/v2/hannah.proto
7
7
  Object.defineProperty(exports, "__esModule", { value: true });
8
- exports.HannahServiceClient = exports.HannahServiceService = exports.protobufPackage = void 0;
8
+ exports.HannahServiceClient = exports.HannahServiceService = exports.HeartbeatResponse = exports.HeartbeatRequest = exports.protobufPackage = void 0;
9
9
  /* eslint-disable */
10
+ const wire_1 = require("@bufbuild/protobuf/wire");
10
11
  const grpc_js_1 = require("@grpc/grpc-js");
11
12
  const activity_log_1 = require("./activity_log");
12
13
  const agent_1 = require("./agent");
@@ -28,6 +29,86 @@ const timer_service_1 = require("./timer_service");
28
29
  const user_registry_1 = require("./user_registry");
29
30
  const wakeword_capture_1 = require("./wakeword_capture");
30
31
  exports.protobufPackage = "hannah.v2";
32
+ function createBaseHeartbeatRequest() {
33
+ return {};
34
+ }
35
+ exports.HeartbeatRequest = {
36
+ encode(_, writer = new wire_1.BinaryWriter()) {
37
+ return writer;
38
+ },
39
+ decode(input, length) {
40
+ const reader = input instanceof wire_1.BinaryReader ? input : new wire_1.BinaryReader(input);
41
+ const previousRecursionDepth = reader.__tsProtoDecodeDepth ?? 0;
42
+ if (previousRecursionDepth >= 100) {
43
+ throw new globalThis.Error("protobuf decode recursion limit exceeded");
44
+ }
45
+ reader.__tsProtoDecodeDepth = previousRecursionDepth + 1;
46
+ try {
47
+ const end = length === undefined ? reader.len : reader.pos + length;
48
+ const message = createBaseHeartbeatRequest();
49
+ while (reader.pos < end) {
50
+ const tag = reader.uint32();
51
+ switch (tag >>> 3) {
52
+ }
53
+ if ((tag & 7) === 4 || tag === 0) {
54
+ break;
55
+ }
56
+ reader.skip(tag & 7);
57
+ }
58
+ return message;
59
+ }
60
+ finally {
61
+ reader.__tsProtoDecodeDepth = previousRecursionDepth;
62
+ }
63
+ },
64
+ create(base) {
65
+ return exports.HeartbeatRequest.fromPartial(base ?? {});
66
+ },
67
+ fromPartial(_) {
68
+ const message = createBaseHeartbeatRequest();
69
+ return message;
70
+ },
71
+ };
72
+ function createBaseHeartbeatResponse() {
73
+ return {};
74
+ }
75
+ exports.HeartbeatResponse = {
76
+ encode(_, writer = new wire_1.BinaryWriter()) {
77
+ return writer;
78
+ },
79
+ decode(input, length) {
80
+ const reader = input instanceof wire_1.BinaryReader ? input : new wire_1.BinaryReader(input);
81
+ const previousRecursionDepth = reader.__tsProtoDecodeDepth ?? 0;
82
+ if (previousRecursionDepth >= 100) {
83
+ throw new globalThis.Error("protobuf decode recursion limit exceeded");
84
+ }
85
+ reader.__tsProtoDecodeDepth = previousRecursionDepth + 1;
86
+ try {
87
+ const end = length === undefined ? reader.len : reader.pos + length;
88
+ const message = createBaseHeartbeatResponse();
89
+ while (reader.pos < end) {
90
+ const tag = reader.uint32();
91
+ switch (tag >>> 3) {
92
+ }
93
+ if ((tag & 7) === 4 || tag === 0) {
94
+ break;
95
+ }
96
+ reader.skip(tag & 7);
97
+ }
98
+ return message;
99
+ }
100
+ finally {
101
+ reader.__tsProtoDecodeDepth = previousRecursionDepth;
102
+ }
103
+ },
104
+ create(base) {
105
+ return exports.HeartbeatResponse.fromPartial(base ?? {});
106
+ },
107
+ fromPartial(_) {
108
+ const message = createBaseHeartbeatResponse();
109
+ return message;
110
+ },
111
+ };
31
112
  exports.HannahServiceService = {
32
113
  /** --- User Registry --- */
33
114
  getUsers: {
@@ -964,5 +1045,18 @@ exports.HannahServiceService = {
964
1045
  responseSerialize: (value) => Buffer.from(shared_1.StatusResponse.encode(value).finish()),
965
1046
  responseDeserialize: (value) => shared_1.StatusResponse.decode(value),
966
1047
  },
1048
+ /**
1049
+ * Liveness signal from a component. The component names itself in the call metadata
1050
+ * (x-component, x-component-version, x-component-id), the message carries nothing yet.
1051
+ */
1052
+ heartbeat: {
1053
+ path: "/hannah.v2.HannahService/Heartbeat",
1054
+ requestStream: false,
1055
+ responseStream: false,
1056
+ requestSerialize: (value) => Buffer.from(exports.HeartbeatRequest.encode(value).finish()),
1057
+ requestDeserialize: (value) => exports.HeartbeatRequest.decode(value),
1058
+ responseSerialize: (value) => Buffer.from(exports.HeartbeatResponse.encode(value).finish()),
1059
+ responseDeserialize: (value) => exports.HeartbeatResponse.decode(value),
1060
+ },
967
1061
  };
968
1062
  exports.HannahServiceClient = (0, grpc_js_1.makeGenericClientConstructor)(exports.HannahServiceService, "hannah.v2.HannahService");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@m1kad0/hannah-proto",
3
- "version": "5.1.0",
3
+ "version": "5.3.0",
4
4
  "description": "Generated TypeScript gRPC-js client stubs for the Hannah voice assistant proto schema",
5
5
  "license": "UNLICENSED",
6
6
  "main": "dist/index.js",