sesame-kit 0.4.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.
Files changed (170) hide show
  1. package/LICENSE +26 -0
  2. package/LICENSE.biz3 +21 -0
  3. package/README.ja.md +225 -0
  4. package/README.md +222 -0
  5. package/bin/sesame.js +8 -0
  6. package/clients/js/sesame-client.mjs +208 -0
  7. package/clients/python/pyproject.toml +5 -0
  8. package/clients/python/sesame_client.py +323 -0
  9. package/clients/python/setup.cfg +11 -0
  10. package/docs/architecture.ja.md +132 -0
  11. package/docs/architecture.md +105 -0
  12. package/docs/commands.ja.md +316 -0
  13. package/docs/commands.md +308 -0
  14. package/docs/library.ja.md +152 -0
  15. package/docs/library.md +152 -0
  16. package/docs/migration.ja.md +13 -0
  17. package/docs/migration.md +13 -0
  18. package/package.json +114 -0
  19. package/src/access.js +375 -0
  20. package/src/account.js +36 -0
  21. package/src/auth.js +248 -0
  22. package/src/ble/devicemodel.js +164 -0
  23. package/src/ble/index.js +185 -0
  24. package/src/ble/protocol.js +319 -0
  25. package/src/ble/session.js +235 -0
  26. package/src/ble/transport.js +279 -0
  27. package/src/cli/access.js +373 -0
  28. package/src/cli/company.js +104 -0
  29. package/src/cli/iot.js +400 -0
  30. package/src/cli/org.js +788 -0
  31. package/src/cli/presetir.js +188 -0
  32. package/src/cli/schedule.js +83 -0
  33. package/src/cli/serve.js +308 -0
  34. package/src/cli.js +1815 -0
  35. package/src/client.js +957 -0
  36. package/src/company.js +147 -0
  37. package/src/config.js +575 -0
  38. package/src/crypto.js +162 -0
  39. package/src/devices.js +228 -0
  40. package/src/index.js +55 -0
  41. package/src/iot.js +513 -0
  42. package/src/ir.js +341 -0
  43. package/src/itemcodes.js +29 -0
  44. package/src/lock.js +194 -0
  45. package/src/org.js +803 -0
  46. package/src/paths.js +30 -0
  47. package/src/presetir.js +525 -0
  48. package/src/prompts.js +74 -0
  49. package/src/schedule.js +108 -0
  50. package/src/serve/daemon.js +251 -0
  51. package/src/serve/framing/grpc.js +145 -0
  52. package/src/serve/framing/http.js +144 -0
  53. package/src/serve/framing/ndjson.js +75 -0
  54. package/src/serve/framing/socket.js +73 -0
  55. package/src/serve/framing/stdio.js +28 -0
  56. package/src/serve/framing/token.js +36 -0
  57. package/src/serve/framing/ws.js +56 -0
  58. package/src/serve/grpc-methods.generated.json +378 -0
  59. package/src/serve/jsonrpc.js +164 -0
  60. package/src/serve/registry.js +226 -0
  61. package/src/serve/rpc-params.generated.json +1746 -0
  62. package/src/serve/sesame.proto +470 -0
  63. package/src/session-ui.js +181 -0
  64. package/src/sharekey.js +130 -0
  65. package/src/tokens.js +53 -0
  66. package/src/transport.js +634 -0
  67. package/src/util.js +26 -0
  68. package/types/access.d.ts +193 -0
  69. package/types/access.d.ts.map +1 -0
  70. package/types/account.d.ts +13 -0
  71. package/types/account.d.ts.map +1 -0
  72. package/types/auth.d.ts +80 -0
  73. package/types/auth.d.ts.map +1 -0
  74. package/types/ble/devicemodel.d.ts +212 -0
  75. package/types/ble/devicemodel.d.ts.map +1 -0
  76. package/types/ble/index.d.ts +160 -0
  77. package/types/ble/index.d.ts.map +1 -0
  78. package/types/ble/protocol.d.ts +201 -0
  79. package/types/ble/protocol.d.ts.map +1 -0
  80. package/types/ble/session.d.ts +129 -0
  81. package/types/ble/session.d.ts.map +1 -0
  82. package/types/ble/transport.d.ts +67 -0
  83. package/types/ble/transport.d.ts.map +1 -0
  84. package/types/cli/access.d.ts +6 -0
  85. package/types/cli/access.d.ts.map +1 -0
  86. package/types/cli/company.d.ts +6 -0
  87. package/types/cli/company.d.ts.map +1 -0
  88. package/types/cli/iot.d.ts +6 -0
  89. package/types/cli/iot.d.ts.map +1 -0
  90. package/types/cli/org.d.ts +6 -0
  91. package/types/cli/org.d.ts.map +1 -0
  92. package/types/cli/presetir.d.ts +6 -0
  93. package/types/cli/presetir.d.ts.map +1 -0
  94. package/types/cli/schedule.d.ts +6 -0
  95. package/types/cli/schedule.d.ts.map +1 -0
  96. package/types/cli/serve.d.ts +2 -0
  97. package/types/cli/serve.d.ts.map +1 -0
  98. package/types/cli.d.ts +2 -0
  99. package/types/cli.d.ts.map +1 -0
  100. package/types/client.d.ts +463 -0
  101. package/types/client.d.ts.map +1 -0
  102. package/types/company.d.ts +94 -0
  103. package/types/company.d.ts.map +1 -0
  104. package/types/config.d.ts +111 -0
  105. package/types/config.d.ts.map +1 -0
  106. package/types/crypto.d.ts +61 -0
  107. package/types/crypto.d.ts.map +1 -0
  108. package/types/devices.d.ts +116 -0
  109. package/types/devices.d.ts.map +1 -0
  110. package/types/index.d.ts +23 -0
  111. package/types/index.d.ts.map +1 -0
  112. package/types/iot.d.ts +312 -0
  113. package/types/iot.d.ts.map +1 -0
  114. package/types/ir.d.ts +147 -0
  115. package/types/ir.d.ts.map +1 -0
  116. package/types/itemcodes.d.ts +21 -0
  117. package/types/itemcodes.d.ts.map +1 -0
  118. package/types/lock.d.ts +89 -0
  119. package/types/lock.d.ts.map +1 -0
  120. package/types/org.d.ts +468 -0
  121. package/types/org.d.ts.map +1 -0
  122. package/types/paths.d.ts +10 -0
  123. package/types/paths.d.ts.map +1 -0
  124. package/types/presetir.d.ts +286 -0
  125. package/types/presetir.d.ts.map +1 -0
  126. package/types/prompts.d.ts +39 -0
  127. package/types/prompts.d.ts.map +1 -0
  128. package/types/schedule.d.ts +71 -0
  129. package/types/schedule.d.ts.map +1 -0
  130. package/types/serve/daemon.d.ts +133 -0
  131. package/types/serve/daemon.d.ts.map +1 -0
  132. package/types/serve/framing/grpc.d.ts +14 -0
  133. package/types/serve/framing/grpc.d.ts.map +1 -0
  134. package/types/serve/framing/http.d.ts +14 -0
  135. package/types/serve/framing/http.d.ts.map +1 -0
  136. package/types/serve/framing/ndjson.d.ts +19 -0
  137. package/types/serve/framing/ndjson.d.ts.map +1 -0
  138. package/types/serve/framing/socket.d.ts +14 -0
  139. package/types/serve/framing/socket.d.ts.map +1 -0
  140. package/types/serve/framing/stdio.d.ts +11 -0
  141. package/types/serve/framing/stdio.d.ts.map +1 -0
  142. package/types/serve/framing/token.d.ts +11 -0
  143. package/types/serve/framing/token.d.ts.map +1 -0
  144. package/types/serve/framing/ws.d.ts +13 -0
  145. package/types/serve/framing/ws.d.ts.map +1 -0
  146. package/types/serve/jsonrpc.d.ts +118 -0
  147. package/types/serve/jsonrpc.d.ts.map +1 -0
  148. package/types/serve/registry.d.ts +41 -0
  149. package/types/serve/registry.d.ts.map +1 -0
  150. package/types/session-ui.d.ts +36 -0
  151. package/types/session-ui.d.ts.map +1 -0
  152. package/types/sharekey.d.ts +35 -0
  153. package/types/sharekey.d.ts.map +1 -0
  154. package/types/tokens.d.ts +20 -0
  155. package/types/tokens.d.ts.map +1 -0
  156. package/types/transport.d.ts +138 -0
  157. package/types/transport.d.ts.map +1 -0
  158. package/types/util.d.ts +20 -0
  159. package/types/util.d.ts.map +1 -0
  160. package/vendor/biz3/README.md +37 -0
  161. package/vendor/biz3/constants/cmdCode.d.ts +48 -0
  162. package/vendor/biz3/constants/cmdCode.d.ts.map +1 -0
  163. package/vendor/biz3/constants/cmdCode.js +92 -0
  164. package/vendor/biz3/constants/messageConstants.d.ts +28 -0
  165. package/vendor/biz3/constants/messageConstants.d.ts.map +1 -0
  166. package/vendor/biz3/constants/messageConstants.js +30 -0
  167. package/vendor/biz3/constants/sesameDeviceModel.d.ts +75 -0
  168. package/vendor/biz3/constants/sesameDeviceModel.d.ts.map +1 -0
  169. package/vendor/biz3/constants/sesameDeviceModel.js +77 -0
  170. package/vendor/biz3/package.json +5 -0
@@ -0,0 +1,75 @@
1
+ // 改行区切り JSON (NDJSON) の Connection ヘルパ。
2
+ // stdio (2 ストリーム) と Unix socket (1 duplex) が共有する。
3
+ //
4
+ // - 手動行分割 (readline は 1 行を無制限にバッファでき OOM DoS。ここは maxLine で上限)。
5
+ // - StringDecoder でチャンク跨ぎのマルチバイト UTF-8 を正しく復元。
6
+ // - 書き込みは背圧 (write/drain) を尊重。出力キューが maxQueue を超えた遅い接続は
7
+ // **その接続だけ** 切る (通知は lossy。デーモン全体は止めない)。
8
+
9
+ import { StringDecoder } from "node:string_decoder";
10
+
11
+ let _idSeq = 0;
12
+
13
+ /**
14
+ * @param {import("node:stream").Readable} readable
15
+ * @param {import("node:stream").Writable} writable
16
+ * @param {{ onLine:(conn:object, raw:string)=>void, onClose?:()=>void,
17
+ * maxQueue?:number, maxLine?:number, closeWritable?:boolean }} opts
18
+ * @returns {{ id:string, send:(obj:object)=>void, close:()=>void }}
19
+ */
20
+ export function makeLineConnection(readable, writable, opts) {
21
+ const { onLine, onClose, maxQueue = 1000, maxLine = 1_000_000, closeWritable = false } = opts;
22
+ let closed = false;
23
+ let draining = false;
24
+ const queue = [];
25
+ const decoder = new StringDecoder("utf8");
26
+ let inbuf = "";
27
+
28
+ const conn = {
29
+ id: `c${++_idSeq}`,
30
+ send(obj) {
31
+ if (closed) return;
32
+ const line = JSON.stringify(obj) + "\n";
33
+ if (draining) {
34
+ queue.push(line);
35
+ if (queue.length > maxQueue) conn.close(); // 追いつけない購読者を切る
36
+ return;
37
+ }
38
+ if (!writable.write(line)) draining = true;
39
+ },
40
+ close() {
41
+ if (closed) return;
42
+ closed = true;
43
+ readable.off("data", onData);
44
+ if (closeWritable) { try { writable.end(); } catch { /* ignore */ } }
45
+ if (onClose) onClose();
46
+ },
47
+ };
48
+
49
+ function onData(chunk) {
50
+ if (closed) return;
51
+ inbuf += decoder.write(chunk);
52
+ let nl;
53
+ while ((nl = inbuf.indexOf("\n")) >= 0) {
54
+ const line = inbuf.slice(0, nl);
55
+ inbuf = inbuf.slice(nl + 1);
56
+ if (line.trim()) onLine(conn, line);
57
+ }
58
+ // 改行が来ないまま 1 行が上限超過 → DoS とみなし切断。
59
+ if (inbuf.length > maxLine) conn.close();
60
+ }
61
+
62
+ writable.on("drain", () => {
63
+ draining = false;
64
+ while (queue.length && !draining) {
65
+ if (!writable.write(queue.shift())) draining = true;
66
+ }
67
+ });
68
+ writable.on("error", () => conn.close());
69
+
70
+ readable.on("data", onData);
71
+ readable.on("end", () => conn.close());
72
+ readable.on("error", () => conn.close());
73
+
74
+ return conn;
75
+ }
@@ -0,0 +1,73 @@
1
+ // Unix domain socket フレーミング: ローカル常駐・多クライアント。NDJSON JSON-RPC。
2
+ // POSIX 専用 (mode 0600。Windows の named pipe は非対象)。
3
+ //
4
+ // 安全性:
5
+ // - listen 前に生存確認 → 別デーモンが生きていれば拒否、stale なら unlink (無条件 unlink しない)。
6
+ // - net.listen は mode を尊重しない (umask 任せ) → umask(0o177) で囲んで 0600 生成。
7
+ // - ソケットは configPaths.dir (0700) 配下に置き、ディレクトリでも二重に守る。
8
+
9
+ import net from "node:net";
10
+ import { existsSync, unlinkSync } from "node:fs";
11
+ import { makeLineConnection } from "./ndjson.js";
12
+
13
+ /** 既存ソケットが生きてれば throw、stale なら unlink して継続。 */
14
+ export function ensureFreeSocket(socketPath) {
15
+ return new Promise((resolve, reject) => {
16
+ if (!existsSync(socketPath)) return resolve();
17
+ const probe = net.connect(socketPath);
18
+ probe.once("connect", () => {
19
+ probe.destroy();
20
+ reject(new Error(`already running (live socket at ${socketPath})`));
21
+ });
22
+ probe.once("error", () => {
23
+ probe.destroy();
24
+ try { unlinkSync(socketPath); } catch { /* ignore */ }
25
+ resolve();
26
+ });
27
+ });
28
+ }
29
+
30
+ /**
31
+ * @param {import("../daemon.js").Daemon} daemon
32
+ * @param {{ socketPath:string }} opts
33
+ * @returns {Promise<{ path:string, stop:()=>Promise<void> }>}
34
+ */
35
+ export async function startSocketFraming(daemon, { socketPath }) {
36
+ await ensureFreeSocket(socketPath);
37
+
38
+ const socks = new Set(); // shutdown 時に能動 destroy するため接続中 socket を追跡
39
+ const server = net.createServer((sock) => {
40
+ socks.add(sock);
41
+ sock.on("close", () => socks.delete(sock));
42
+ let conn;
43
+ conn = makeLineConnection(sock, sock, {
44
+ onLine: (c, raw) => daemon.handleLine(c, raw),
45
+ onClose: () => daemon.removeConnection(conn),
46
+ closeWritable: true,
47
+ });
48
+ daemon.addConnection(conn);
49
+ sock.on("error", () => conn.close());
50
+ sock.on("close", () => conn.close());
51
+ });
52
+
53
+ // 0600 で生成するため listen を umask で囲む (callback で必ず復元)。
54
+ const oldUmask = process.umask(0o177);
55
+ try {
56
+ await new Promise((resolve, reject) => {
57
+ server.once("error", reject);
58
+ server.listen(socketPath, () => resolve());
59
+ });
60
+ } finally {
61
+ process.umask(oldUmask);
62
+ }
63
+
64
+ return {
65
+ path: socketPath,
66
+ // 接続中の購読者がいても即終了するため socket を能動 destroy してから close
67
+ // (これをしないと server.close は全接続が自発切断するまで callback を発火せずハングする)。
68
+ stop: () => new Promise((resolve) => {
69
+ for (const s of socks) { try { s.destroy(); } catch { /* ignore */ } }
70
+ server.close(() => resolve());
71
+ }),
72
+ };
73
+ }
@@ -0,0 +1,28 @@
1
+ // stdio フレーミング: stdin/stdout で NDJSON JSON-RPC。埋め込み (親が子プロセスとして spawn) 用。
2
+ // 単一 Connection。stdin EOF (親が死んだ) で graceful shutdown を起こす。
3
+
4
+ import { makeLineConnection } from "./ndjson.js";
5
+ import { makeEvent } from "../jsonrpc.js";
6
+
7
+ /**
8
+ * @param {import("../daemon.js").Daemon} daemon
9
+ * @param {{ onShutdown?:()=>void }} [opts]
10
+ * @returns {{ stop:()=>void }}
11
+ */
12
+ export function startStdioFraming(daemon, { onShutdown } = {}) {
13
+ let conn;
14
+ conn = makeLineConnection(process.stdin, process.stdout, {
15
+ onLine: (c, raw) => daemon.handleLine(c, raw),
16
+ onClose: () => {
17
+ daemon.removeConnection(conn);
18
+ if (onShutdown) onShutdown(); // stdin EOF = 親終了 → デーモンも畳む
19
+ },
20
+ // stdout はプロセス共有なので閉じない (closeWritable=false)
21
+ });
22
+ daemon.addConnection(conn);
23
+ // 準備完了を **stdout の通常チャネル** で通知する (event.ready)。stderr を読む非通念な
24
+ // 儀式を不要にする。早期に書かれた入力は OS パイプが buffer するので待たなくても良いが、
25
+ // 待ちたいクライアントはこの 1 本を見れば良い (全言語が既に demux するチャネル)。
26
+ conn.send(makeEvent("ready", {}));
27
+ return { stop() { conn.close(); } };
28
+ }
@@ -0,0 +1,36 @@
1
+ // ネットワーク系フレーミング (HTTP/WS/gRPC) 共通の loopback token 認証。
2
+ // 同一ユーザの UDS と違い TCP は他プロセス/ブラウザからも届くので、起動時に生成した
3
+ // 秘密 token を要求する (CSRF/他ユーザ対策)。比較は定数時間。
4
+ import { randomBytes, timingSafeEqual } from "node:crypto";
5
+
6
+ /** 32byte hex のランダム token。 */
7
+ export function generateToken() {
8
+ return randomBytes(32).toString("hex");
9
+ }
10
+
11
+ /** 定数時間比較。長さ不一致は false。 */
12
+ export function tokenMatches(provided, expected) {
13
+ if (typeof provided !== "string" || typeof expected !== "string") return false;
14
+ if (provided.length !== expected.length) return false;
15
+ try {
16
+ return timingSafeEqual(Buffer.from(provided), Buffer.from(expected));
17
+ } catch {
18
+ return false;
19
+ }
20
+ }
21
+
22
+ /**
23
+ * HTTP リクエストから token を取り出す。**通常は `Authorization: Bearer` ヘッダ**を使うこと。
24
+ * `?token=` クエリは **ブラウザ専用のフォールバック** (EventSource/WebSocket がヘッダを送れないため)。
25
+ * クエリに載せると proxy ログ/履歴に残るので、ヘッダを送れるクライアントは必ずヘッダを使う。
26
+ */
27
+ export function extractToken(req) {
28
+ const auth = req.headers?.authorization || "";
29
+ const m = /^Bearer\s+(.+)$/i.exec(auth);
30
+ if (m) return m[1];
31
+ try {
32
+ return new URL(req.url, "http://localhost").searchParams.get("token") || "";
33
+ } catch {
34
+ return "";
35
+ }
36
+ }
@@ -0,0 +1,56 @@
1
+ // WebSocket フレーミング: 全二重。ブラウザ/全言語から JSON-RPC を双方向で。
2
+ // 1 接続 = 持続 Connection。events.subscribe で event 通知がそのまま流れる。
3
+ // 接続時に loopback token (?token= / Authorization: Bearer) を要求。
4
+
5
+ import { WebSocketServer } from "ws";
6
+ import { tokenMatches, extractToken } from "./token.js";
7
+
8
+ const MAX_BUFFERED = 4 * 1024 * 1024; // 4MB を超えて溜まった遅い購読者は切る (背圧)
9
+
10
+ /**
11
+ * @param {import("../daemon.js").Daemon} daemon
12
+ * @param {{ bind?:string, port:number, token:string }} opts
13
+ * @returns {Promise<{ stop:()=>Promise<void> }>}
14
+ */
15
+ export async function startWsFraming(daemon, { bind = "127.0.0.1", port, token }) {
16
+ // 握手前 (HTTP upgrade) に token を検証し、失敗は 101 を返さず 401 で弾く。
17
+ // これで未認証クライアントの open は発火せず error になる (close 1008 は握手後で open に先を越され
18
+ // クライアントが認証失敗を取りこぼすため、ここで止めるのが正しい)。
19
+ const verifyClient = (info) => tokenMatches(extractToken(info.req), token);
20
+ const wss = new WebSocketServer({ host: bind, port, verifyClient });
21
+
22
+ wss.on("connection", (ws, req) => {
23
+ // verifyClient で認証済みだが、防御的に再確認 (verifyClient 無効化時の保険)。
24
+ if (!tokenMatches(extractToken(req), token)) {
25
+ try { ws.close(1008, "unauthorized"); } catch { /* ignore */ }
26
+ return;
27
+ }
28
+ const conn = {
29
+ id: "ws",
30
+ send: (obj) => {
31
+ if (ws.bufferedAmount > MAX_BUFFERED) { conn.close(); return; } // 追いつけない購読者を切る
32
+ try { ws.send(JSON.stringify(obj)); } catch { /* closed */ }
33
+ },
34
+ close: () => { try { ws.close(); } catch { /* ignore */ } },
35
+ };
36
+ daemon.addConnection(conn);
37
+ ws.on("message", (data) => daemon.handleLine(conn, data.toString()));
38
+ ws.on("close", () => daemon.removeConnection(conn));
39
+ ws.on("error", () => conn.close());
40
+ });
41
+
42
+ await new Promise((resolve, reject) => {
43
+ wss.once("error", reject);
44
+ wss.once("listening", () => resolve());
45
+ });
46
+
47
+ return {
48
+ port: wss.address().port,
49
+ url: `ws://${bind}:${wss.address().port}`,
50
+ // 購読中クライアントを terminate してから close (しないと wss.close は接続が残る限りハング)。
51
+ stop: () => new Promise((resolve) => {
52
+ for (const c of wss.clients) { try { c.terminate(); } catch { /* ignore */ } }
53
+ wss.close(() => resolve());
54
+ }),
55
+ };
56
+ }
@@ -0,0 +1,378 @@
1
+ {
2
+ "ScheduleGetScheduleList": {
3
+ "method": "schedule.getScheduleList",
4
+ "jsonFields": []
5
+ },
6
+ "ScheduleCancelSchedule": {
7
+ "method": "schedule.cancelSchedule",
8
+ "jsonFields": []
9
+ },
10
+ "OrgGetEmployees": {
11
+ "method": "org.getEmployees",
12
+ "jsonFields": []
13
+ },
14
+ "OrgGetCurrentUserInfo": {
15
+ "method": "org.getCurrentUserInfo",
16
+ "jsonFields": []
17
+ },
18
+ "OrgAddEmployees": {
19
+ "method": "org.addEmployees",
20
+ "jsonFields": [
21
+ "items"
22
+ ]
23
+ },
24
+ "OrgUpdateEmployee": {
25
+ "method": "org.updateEmployee",
26
+ "jsonFields": [
27
+ "data"
28
+ ]
29
+ },
30
+ "OrgRemoveEmployees": {
31
+ "method": "org.removeEmployees",
32
+ "jsonFields": [
33
+ "items"
34
+ ]
35
+ },
36
+ "OrgReorderEmployees": {
37
+ "method": "org.reorderEmployees",
38
+ "jsonFields": [
39
+ "items"
40
+ ]
41
+ },
42
+ "OrgQueryByCS": {
43
+ "method": "org.queryByCS",
44
+ "jsonFields": []
45
+ },
46
+ "OrgConfirmQueryByCS": {
47
+ "method": "org.confirmQueryByCS",
48
+ "jsonFields": []
49
+ },
50
+ "OrgGetEmployeeGroups": {
51
+ "method": "org.getEmployeeGroups",
52
+ "jsonFields": []
53
+ },
54
+ "OrgAddEmployeeGroup": {
55
+ "method": "org.addEmployeeGroup",
56
+ "jsonFields": [
57
+ "item"
58
+ ]
59
+ },
60
+ "OrgUpdateEmployeeGroup": {
61
+ "method": "org.updateEmployeeGroup",
62
+ "jsonFields": [
63
+ "item"
64
+ ]
65
+ },
66
+ "OrgRemoveEmployeeGroups": {
67
+ "method": "org.removeEmployeeGroups",
68
+ "jsonFields": [
69
+ "gids"
70
+ ]
71
+ },
72
+ "OrgGetEmployeeGroupBindDeviceGroup": {
73
+ "method": "org.getEmployeeGroupBindDeviceGroup",
74
+ "jsonFields": []
75
+ },
76
+ "OrgAddEmployeeInGroup": {
77
+ "method": "org.addEmployeeInGroup",
78
+ "jsonFields": [
79
+ "uuids",
80
+ "items"
81
+ ]
82
+ },
83
+ "OrgRemoveEmployeeInGroup": {
84
+ "method": "org.removeEmployeeInGroup",
85
+ "jsonFields": [
86
+ "uuids",
87
+ "items"
88
+ ]
89
+ },
90
+ "OrgRemoveEmployeeGroupBindDeviceGroup": {
91
+ "method": "org.removeEmployeeGroupBindDeviceGroup",
92
+ "jsonFields": [
93
+ "data"
94
+ ]
95
+ },
96
+ "OrgGetTags": {
97
+ "method": "org.getTags",
98
+ "jsonFields": []
99
+ },
100
+ "OrgPostTag": {
101
+ "method": "org.postTag",
102
+ "jsonFields": [
103
+ "data"
104
+ ]
105
+ },
106
+ "OrgRemoveTag": {
107
+ "method": "org.removeTag",
108
+ "jsonFields": [
109
+ "data"
110
+ ]
111
+ },
112
+ "OrgGetDeviceGroups": {
113
+ "method": "org.getDeviceGroups",
114
+ "jsonFields": []
115
+ },
116
+ "OrgAddDeviceGroup": {
117
+ "method": "org.addDeviceGroup",
118
+ "jsonFields": []
119
+ },
120
+ "OrgUpdateDeviceGroup": {
121
+ "method": "org.updateDeviceGroup",
122
+ "jsonFields": [
123
+ "item"
124
+ ]
125
+ },
126
+ "OrgRemoveDeviceGroups": {
127
+ "method": "org.removeDeviceGroups",
128
+ "jsonFields": [
129
+ "groupIds"
130
+ ]
131
+ },
132
+ "OrgAddDeviceInGroup": {
133
+ "method": "org.addDeviceInGroup",
134
+ "jsonFields": [
135
+ "uuids",
136
+ "items"
137
+ ]
138
+ },
139
+ "OrgRemoveDeviceInGroup": {
140
+ "method": "org.removeDeviceInGroup",
141
+ "jsonFields": [
142
+ "uuids",
143
+ "items"
144
+ ]
145
+ },
146
+ "OrgGetDeviceGroupBindUserGroup": {
147
+ "method": "org.getDeviceGroupBindUserGroup",
148
+ "jsonFields": []
149
+ },
150
+ "OrgRemoveDeviceGroupBindUserGroup": {
151
+ "method": "org.removeDeviceGroupBindUserGroup",
152
+ "jsonFields": [
153
+ "data"
154
+ ]
155
+ },
156
+ "OrgShareDeviceKeysToEmployees": {
157
+ "method": "org.shareDeviceKeysToEmployees",
158
+ "jsonFields": [
159
+ "items"
160
+ ]
161
+ },
162
+ "OrgShareDeviceGroupKeysToEmployeeGroup": {
163
+ "method": "org.shareDeviceGroupKeysToEmployeeGroup",
164
+ "jsonFields": [
165
+ "item"
166
+ ]
167
+ },
168
+ "OrgGetEmployeeDeviceKeys": {
169
+ "method": "org.getEmployeeDeviceKeys",
170
+ "jsonFields": []
171
+ },
172
+ "OrgRemoveEmployeeDeviceKey": {
173
+ "method": "org.removeEmployeeDeviceKey",
174
+ "jsonFields": [
175
+ "data"
176
+ ]
177
+ },
178
+ "OrgUpdateGuestKeyTag": {
179
+ "method": "org.updateGuestKeyTag",
180
+ "jsonFields": [
181
+ "data"
182
+ ]
183
+ },
184
+ "OrgGenerateGuestQR": {
185
+ "method": "org.generateGuestQR",
186
+ "jsonFields": [
187
+ "data"
188
+ ]
189
+ },
190
+ "OrgGetDeviceEmployeeKeys": {
191
+ "method": "org.getDeviceEmployeeKeys",
192
+ "jsonFields": []
193
+ },
194
+ "CompanyGetCompanies": {
195
+ "method": "company.getCompanies",
196
+ "jsonFields": []
197
+ },
198
+ "CompanyUpdateCompanyName": {
199
+ "method": "company.updateCompanyName",
200
+ "jsonFields": []
201
+ },
202
+ "CompanyAddCompany": {
203
+ "method": "company.addCompany",
204
+ "jsonFields": []
205
+ },
206
+ "CompanyGetPaymentConfig": {
207
+ "method": "company.getPaymentConfig",
208
+ "jsonFields": []
209
+ },
210
+ "AccessGetCards": {
211
+ "method": "access.getCards",
212
+ "jsonFields": []
213
+ },
214
+ "AccessGetPasscodes": {
215
+ "method": "access.getPasscodes",
216
+ "jsonFields": []
217
+ },
218
+ "AccessPostCards": {
219
+ "method": "access.postCards",
220
+ "jsonFields": [
221
+ "list"
222
+ ]
223
+ },
224
+ "AccessPostPasscodes": {
225
+ "method": "access.postPasscodes",
226
+ "jsonFields": [
227
+ "list"
228
+ ]
229
+ },
230
+ "AccessDelCards": {
231
+ "method": "access.delCards",
232
+ "jsonFields": [
233
+ "items"
234
+ ]
235
+ },
236
+ "AccessDelPasscodes": {
237
+ "method": "access.delPasscodes",
238
+ "jsonFields": [
239
+ "items"
240
+ ]
241
+ },
242
+ "AccessClearCards": {
243
+ "method": "access.clearCards",
244
+ "jsonFields": []
245
+ },
246
+ "AccessClearPasscodes": {
247
+ "method": "access.clearPasscodes",
248
+ "jsonFields": []
249
+ },
250
+ "AccessUpdateCardName": {
251
+ "method": "access.updateCardName",
252
+ "jsonFields": [
253
+ "item"
254
+ ]
255
+ },
256
+ "AccessUpdatePasscodeName": {
257
+ "method": "access.updatePasscodeName",
258
+ "jsonFields": [
259
+ "item"
260
+ ]
261
+ },
262
+ "AccessUpdateCardOwner": {
263
+ "method": "access.updateCardOwner",
264
+ "jsonFields": []
265
+ },
266
+ "IotSendIotCmd": {
267
+ "method": "iot.sendIotCmd",
268
+ "jsonFields": []
269
+ },
270
+ "IotSubscribeIotResponse": {
271
+ "method": "iot.subscribeIotResponse",
272
+ "jsonFields": [
273
+ "params"
274
+ ]
275
+ },
276
+ "IotSendIotCmdAwait": {
277
+ "method": "iot.sendIotCmdAwait",
278
+ "jsonFields": []
279
+ },
280
+ "IotSetHub3LedDuty": {
281
+ "method": "iot.setHub3LedDuty",
282
+ "jsonFields": []
283
+ },
284
+ "IotHub3RelaySwitch": {
285
+ "method": "iot.hub3RelaySwitch",
286
+ "jsonFields": []
287
+ },
288
+ "IotAddSesameToHub3": {
289
+ "method": "iot.addSesameToHub3",
290
+ "jsonFields": []
291
+ },
292
+ "IotRemoveSesameFromHub3": {
293
+ "method": "iot.removeSesameFromHub3",
294
+ "jsonFields": [
295
+ "params"
296
+ ]
297
+ },
298
+ "IotStartFirmwareUpdate": {
299
+ "method": "iot.startFirmwareUpdate",
300
+ "jsonFields": []
301
+ },
302
+ "IotClearHub3WifiSsid": {
303
+ "method": "iot.clearHub3WifiSsid",
304
+ "jsonFields": []
305
+ },
306
+ "IotGetMatterPairingCode": {
307
+ "method": "iot.getMatterPairingCode",
308
+ "jsonFields": []
309
+ },
310
+ "IotOpenMatterPairingWindow": {
311
+ "method": "iot.openMatterPairingWindow",
312
+ "jsonFields": []
313
+ },
314
+ "PresetirSendIR": {
315
+ "method": "presetir.sendIR",
316
+ "jsonFields": []
317
+ },
318
+ "PresetirEmitAir": {
319
+ "method": "presetir.emitAir",
320
+ "jsonFields": []
321
+ },
322
+ "PresetirEmitButton": {
323
+ "method": "presetir.emitButton",
324
+ "jsonFields": []
325
+ },
326
+ "Status": {
327
+ "method": "status",
328
+ "jsonFields": []
329
+ },
330
+ "AccountWhoami": {
331
+ "method": "account.whoami",
332
+ "jsonFields": []
333
+ },
334
+ "LockLock": {
335
+ "method": "lock.lock",
336
+ "jsonFields": []
337
+ },
338
+ "LockUnlock": {
339
+ "method": "lock.unlock",
340
+ "jsonFields": []
341
+ },
342
+ "LockToggle": {
343
+ "method": "lock.toggle",
344
+ "jsonFields": []
345
+ },
346
+ "LockClick": {
347
+ "method": "lock.click",
348
+ "jsonFields": []
349
+ },
350
+ "LockStatus": {
351
+ "method": "lock.status",
352
+ "jsonFields": []
353
+ },
354
+ "DevicesList": {
355
+ "method": "devices.list",
356
+ "jsonFields": []
357
+ },
358
+ "DeviceHistory": {
359
+ "method": "device.history",
360
+ "jsonFields": []
361
+ },
362
+ "DeviceBattery": {
363
+ "method": "device.battery",
364
+ "jsonFields": []
365
+ },
366
+ "IrSend": {
367
+ "method": "ir.send",
368
+ "jsonFields": []
369
+ },
370
+ "IrListKeys": {
371
+ "method": "ir.listKeys",
372
+ "jsonFields": []
373
+ },
374
+ "Discover": {
375
+ "method": "rpc.discover",
376
+ "jsonFields": []
377
+ }
378
+ }