@camstack/addon-provider-tuya 0.2.140 → 0.2.141
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/addon.js +115 -62
- package/dist/addon.mjs +115 -62
- package/i18n/en.json +1 -1
- package/i18n/it.json +1 -1
- package/package.json +1 -1
package/dist/addon.js
CHANGED
|
@@ -819,7 +819,7 @@ async function discoverDevices(options = {}, binder = createDgramBinder()) {
|
|
|
819
819
|
return [...byId.values()];
|
|
820
820
|
}
|
|
821
821
|
//#endregion
|
|
822
|
-
//#region ../types/dist/event-category-
|
|
822
|
+
//#region ../types/dist/event-category-BfJwUd2S.mjs
|
|
823
823
|
var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
824
824
|
EventCategory["SystemBoot"] = "system.boot";
|
|
825
825
|
EventCategory["SystemAddonsReady"] = "system.addons-ready";
|
|
@@ -1136,6 +1136,15 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
|
1136
1136
|
*/
|
|
1137
1137
|
EventCategory["PipelineDetectionBlind"] = "pipeline.detection-blind";
|
|
1138
1138
|
/**
|
|
1139
|
+
* A camera's motion source has fired constantly with no subject for an hour
|
|
1140
|
+
* (motion duty or session count over the bar, zero detections) — it is not
|
|
1141
|
+
* blind, its motion zones or sensitivity want tuning (D907). Paired with
|
|
1142
|
+
* {@link PipelineMotionCalm}.
|
|
1143
|
+
*/
|
|
1144
|
+
EventCategory["PipelineMotionNoisy"] = "pipeline.motion-noisy";
|
|
1145
|
+
/** The recovery edge of {@link PipelineMotionNoisy}: the motion fell back, or a detection arrived. */
|
|
1146
|
+
EventCategory["PipelineMotionCalm"] = "pipeline.motion-calm";
|
|
1147
|
+
/**
|
|
1139
1148
|
* Per-camera pipeline config was mutated by the orchestrator
|
|
1140
1149
|
* (3-level settings change via `setAgentAddonDefaults` /
|
|
1141
1150
|
* `setCameraStepToggle` / `setCameraPipelineForAgent` or a
|
|
@@ -6242,7 +6251,7 @@ var ZodIssueCode = {
|
|
|
6242
6251
|
var ZodFirstPartyTypeKind;
|
|
6243
6252
|
ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
|
|
6244
6253
|
//#endregion
|
|
6245
|
-
//#region ../types/dist/sleep-
|
|
6254
|
+
//#region ../types/dist/sleep-DJFUfKvA.mjs
|
|
6246
6255
|
/**
|
|
6247
6256
|
* The audio chunk plane's byte format, and the ONE expansion from a coded
|
|
6248
6257
|
* window to float samples (D455).
|
|
@@ -8771,7 +8780,7 @@ var EntryDescriptorSchema = object({
|
|
|
8771
8780
|
/** JSON Schema of the entry body; `secret: true` marks a password field. */
|
|
8772
8781
|
fields: record(string(), unknown())
|
|
8773
8782
|
}).strict();
|
|
8774
|
-
/** What crosses the wire
|
|
8783
|
+
/** What crosses the wire from an addon: JSON only, no Zod. An unknown key is refused. */
|
|
8775
8784
|
var RecordKindDeclarationSchema = object({
|
|
8776
8785
|
database: _enum(RECORD_DATABASES).default("settings"),
|
|
8777
8786
|
class: _enum(RECORD_CLASSES),
|
|
@@ -8790,14 +8799,6 @@ var RecordKindDeclarationSchema = object({
|
|
|
8790
8799
|
secretPaths: array(string().min(1)).default([]),
|
|
8791
8800
|
/** The id key of each array that carries a secret (`{ headers: 'name' }`). */
|
|
8792
8801
|
secretArrayKeys: record(string(), string()).default({}),
|
|
8793
|
-
/**
|
|
8794
|
-
* RETIRED (D900): the legacy table a kind adopted from during the records
|
|
8795
|
-
* migration. Nothing declares it any more and nothing reads it; the schema
|
|
8796
|
-
* still ACCEPTS it because the catalog rows the migration wrote carry it
|
|
8797
|
-
* (an orphaned kind is never redeclared) and an addon built before the
|
|
8798
|
-
* removal still sends it. Never set it.
|
|
8799
|
-
*/
|
|
8800
|
-
adoptsFrom: string().min(1).optional(),
|
|
8801
8802
|
/** Kinds that must agree through `transact` sit in one file under one family name. */
|
|
8802
8803
|
transactFamily: string().min(1).optional(),
|
|
8803
8804
|
entry: EntryDescriptorSchema.optional()
|
|
@@ -13475,17 +13476,6 @@ object({
|
|
|
13475
13476
|
createdAt: number(),
|
|
13476
13477
|
updatedAt: number()
|
|
13477
13478
|
});
|
|
13478
|
-
object({
|
|
13479
|
-
id: string(),
|
|
13480
|
-
label: string(),
|
|
13481
|
-
isAdmin: boolean().default(false),
|
|
13482
|
-
allowedProviders: AllowedProviderSchema,
|
|
13483
|
-
allowedDevices: AllowedDevicesSchema,
|
|
13484
|
-
tokenHash: string(),
|
|
13485
|
-
tokenPrefix: string(),
|
|
13486
|
-
createdAt: number(),
|
|
13487
|
-
lastUsedAt: number().optional()
|
|
13488
|
-
});
|
|
13489
13479
|
object({
|
|
13490
13480
|
id: string(),
|
|
13491
13481
|
userId: string(),
|
|
@@ -17467,16 +17457,36 @@ var RecordKindStateSchema = _enum([
|
|
|
17467
17457
|
var DeclareKindResultSchema = object({
|
|
17468
17458
|
kindId: number().int(),
|
|
17469
17459
|
state: RecordKindStateSchema,
|
|
17470
|
-
createdIndexes: array(string())
|
|
17471
|
-
/**
|
|
17472
|
-
* RETIRED (D900): always `null`. It carried the records-migration boot guard;
|
|
17473
|
-
* it stays on the wire, null, because an addon built before the removal reads
|
|
17474
|
-
* an ABSENT field as "adoption pending" and refuses to start.
|
|
17475
|
-
*/
|
|
17476
|
-
adoptionPending: _null()
|
|
17460
|
+
createdIndexes: array(string())
|
|
17477
17461
|
});
|
|
17478
17462
|
/** Keychain refs a write released (the old marker is gone from the row): the owner deletes the values. */
|
|
17479
17463
|
var SecretRefsList = array(string());
|
|
17464
|
+
/**
|
|
17465
|
+
* One op of a `transact`: the single-row writes, each on a kind of the caller.
|
|
17466
|
+
* All ops of one call share ONE database file and ONE `transactFamily`.
|
|
17467
|
+
*/
|
|
17468
|
+
var RecordTransactOpSchema = discriminatedUnion("op", [
|
|
17469
|
+
object({
|
|
17470
|
+
op: literal("put"),
|
|
17471
|
+
kind: RecordKindNameSchema,
|
|
17472
|
+
record: RecordInputSchema,
|
|
17473
|
+
ifRev: number().int().min(0).optional()
|
|
17474
|
+
}),
|
|
17475
|
+
object({
|
|
17476
|
+
op: literal("patch"),
|
|
17477
|
+
kind: RecordKindNameSchema,
|
|
17478
|
+
id: RecordIdSchema,
|
|
17479
|
+
data: RecordBodySchema,
|
|
17480
|
+
at: number().int().nullable().optional(),
|
|
17481
|
+
expiresAt: number().int().nullable().optional(),
|
|
17482
|
+
ifRev: number().int().min(1).optional()
|
|
17483
|
+
}),
|
|
17484
|
+
object({
|
|
17485
|
+
op: literal("delete"),
|
|
17486
|
+
kind: RecordKindNameSchema,
|
|
17487
|
+
id: RecordIdSchema
|
|
17488
|
+
})
|
|
17489
|
+
]);
|
|
17480
17490
|
var RecordSecretRefsSchema = record(string(), record(string(), string()));
|
|
17481
17491
|
method(object({ kinds: record(RecordKindNameSchema, RecordKindDeclarationSchema) }), object({ kinds: record(string(), DeclareKindResultSchema) }), {
|
|
17482
17492
|
kind: "mutation",
|
|
@@ -17583,6 +17593,16 @@ method(object({ kinds: record(RecordKindNameSchema, RecordKindDeclarationSchema)
|
|
|
17583
17593
|
}), {
|
|
17584
17594
|
kind: "mutation",
|
|
17585
17595
|
auth: "admin"
|
|
17596
|
+
}), method(object({ ops: array(RecordTransactOpSchema).min(1).max(RECORD_BATCH_MAX) }), object({
|
|
17597
|
+
results: array(object({
|
|
17598
|
+
rev: number().int().nullable(),
|
|
17599
|
+
deleted: boolean()
|
|
17600
|
+
})),
|
|
17601
|
+
releasedRefs: SecretRefsList,
|
|
17602
|
+
secretRefs: SecretRefsList
|
|
17603
|
+
}), {
|
|
17604
|
+
kind: "mutation",
|
|
17605
|
+
auth: "admin"
|
|
17586
17606
|
}), method(object({
|
|
17587
17607
|
deviceId: number().int(),
|
|
17588
17608
|
kinds: array(RecordKindNameSchema).optional()
|
|
@@ -43194,9 +43214,13 @@ var NcSystemEventKindSchema = _enum([
|
|
|
43194
43214
|
"node-updating",
|
|
43195
43215
|
"node-inference-unavailable",
|
|
43196
43216
|
"detection-blind",
|
|
43217
|
+
"motion-noisy",
|
|
43218
|
+
"motion-calm",
|
|
43197
43219
|
"recording-stalled",
|
|
43198
43220
|
"recording-healthy",
|
|
43199
43221
|
"recording-degraded",
|
|
43222
|
+
"device-attention-required",
|
|
43223
|
+
"device-attention-resolved",
|
|
43200
43224
|
"storage-location-low",
|
|
43201
43225
|
"storage-location-critical",
|
|
43202
43226
|
"storage-location-ok",
|
|
@@ -56528,6 +56552,16 @@ var DishwasherStatusSchema = object({
|
|
|
56528
56552
|
powerState: string().nullable(),
|
|
56529
56553
|
saltLevel: DishwasherConsumableLevelSchema.nullable(),
|
|
56530
56554
|
rinseAidLevel: DishwasherConsumableLevelSchema.nullable(),
|
|
56555
|
+
/**
|
|
56556
|
+
* True while the appliance asks for its filter to be cleaned (smart-filter, filter-system or
|
|
56557
|
+
* combined care-and-filter reminder raised); false when every such reminder reads clear; null
|
|
56558
|
+
* when none is reported. A cleared reminder is not an unknown one.
|
|
56559
|
+
*/
|
|
56560
|
+
filterCleaningDue: boolean().nullable(),
|
|
56561
|
+
/** True while the machine-care (descaling / cleaning-program) reminder is raised; false when clear; null when not reported. */
|
|
56562
|
+
machineCareDue: boolean().nullable(),
|
|
56563
|
+
/** Program runs left before the machine-care reminder is due; null when the appliance does not say. */
|
|
56564
|
+
machineCareRemainingRuns: number().int().nonnegative().nullable(),
|
|
56531
56565
|
/** Option states: null when the appliance does not expose the option or has not said. */
|
|
56532
56566
|
halfLoad: boolean().nullable(),
|
|
56533
56567
|
hygienePlus: boolean().nullable(),
|
|
@@ -65178,16 +65212,6 @@ var UpdateUserInputSchema = object({
|
|
|
65178
65212
|
allowedDevices: record(string(), union([array(string()), literal("*")])).optional(),
|
|
65179
65213
|
scopes: array(TokenScopeSchema).optional()
|
|
65180
65214
|
});
|
|
65181
|
-
var ApiKeySummarySchema = object({
|
|
65182
|
-
id: string(),
|
|
65183
|
-
label: string(),
|
|
65184
|
-
isAdmin: boolean().default(false),
|
|
65185
|
-
allowedProviders: union([array(string()), literal("*")]).optional(),
|
|
65186
|
-
allowedDevices: record(string(), union([array(string()), literal("*")])).optional(),
|
|
65187
|
-
tokenPrefix: string(),
|
|
65188
|
-
createdAt: number(),
|
|
65189
|
-
lastUsedAt: number().optional()
|
|
65190
|
-
});
|
|
65191
65215
|
var OauthSessionSummarySchema = object({
|
|
65192
65216
|
id: string(),
|
|
65193
65217
|
userId: string(),
|
|
@@ -65209,8 +65233,7 @@ var TotpStatusSchema = object({
|
|
|
65209
65233
|
confirmedAt: number().nullable()
|
|
65210
65234
|
});
|
|
65211
65235
|
/**
|
|
65212
|
-
* user-management — singleton capability for user accounts
|
|
65213
|
-
* legacy API-key rows.
|
|
65236
|
+
* user-management — singleton capability for user accounts.
|
|
65214
65237
|
*
|
|
65215
65238
|
* v2 model: every method gated by `auth: 'admin'`. Admin-only delegation
|
|
65216
65239
|
* — the subset check on `setUserScopes` is moot
|
|
@@ -65266,10 +65289,6 @@ method(_void(), array(UserSummarySchema), { auth: "admin" }), method(CreateUserI
|
|
|
65266
65289
|
}), UserSummarySchema.extend({ passwordHash: string() }).nullable(), {
|
|
65267
65290
|
kind: "mutation",
|
|
65268
65291
|
access: "view"
|
|
65269
|
-
}), method(_void(), array(ApiKeySummarySchema), { auth: "admin" }), method(object({ id: string() }), object({ success: literal(true) }), {
|
|
65270
|
-
kind: "mutation",
|
|
65271
|
-
auth: "admin",
|
|
65272
|
-
access: "delete"
|
|
65273
65292
|
}), method(object({ userId: string() }), TotpSetupResultSchema, {
|
|
65274
65293
|
kind: "mutation",
|
|
65275
65294
|
auth: "admin",
|
|
@@ -74725,6 +74744,12 @@ Object.freeze({
|
|
|
74725
74744
|
addonId: null,
|
|
74726
74745
|
access: "view"
|
|
74727
74746
|
},
|
|
74747
|
+
"records.transact": {
|
|
74748
|
+
capName: "records",
|
|
74749
|
+
capScope: "system",
|
|
74750
|
+
addonId: null,
|
|
74751
|
+
access: "create"
|
|
74752
|
+
},
|
|
74728
74753
|
"sceneMonitor.captureReference": {
|
|
74729
74754
|
capName: "scene-monitor",
|
|
74730
74755
|
capScope: "device",
|
|
@@ -76057,12 +76082,6 @@ Object.freeze({
|
|
|
76057
76082
|
addonId: null,
|
|
76058
76083
|
access: "view"
|
|
76059
76084
|
},
|
|
76060
|
-
"userManagement.listApiKeys": {
|
|
76061
|
-
capName: "user-management",
|
|
76062
|
-
capScope: "system",
|
|
76063
|
-
addonId: null,
|
|
76064
|
-
access: "view"
|
|
76065
|
-
},
|
|
76066
76085
|
"userManagement.listExternalIdentities": {
|
|
76067
76086
|
capName: "user-management",
|
|
76068
76087
|
capScope: "system",
|
|
@@ -76117,12 +76136,6 @@ Object.freeze({
|
|
|
76117
76136
|
addonId: null,
|
|
76118
76137
|
access: "create"
|
|
76119
76138
|
},
|
|
76120
|
-
"userManagement.revokeApiKey": {
|
|
76121
|
-
capName: "user-management",
|
|
76122
|
-
capScope: "system",
|
|
76123
|
-
addonId: null,
|
|
76124
|
-
access: "delete"
|
|
76125
|
-
},
|
|
76126
76139
|
"userManagement.revokeOauthSession": {
|
|
76127
76140
|
capName: "user-management",
|
|
76128
76141
|
capScope: "system",
|
|
@@ -79487,9 +79500,13 @@ new Map(Object.entries({
|
|
|
79487
79500
|
"stream-online": "device-events",
|
|
79488
79501
|
"stream-offline": "device-events",
|
|
79489
79502
|
"detection-blind": "device-events",
|
|
79503
|
+
"motion-noisy": "device-events",
|
|
79504
|
+
"motion-calm": "device-events",
|
|
79490
79505
|
"recording-stalled": "device-events",
|
|
79491
79506
|
"recording-healthy": "device-events",
|
|
79492
79507
|
"recording-degraded": "device-events",
|
|
79508
|
+
"device-attention-required": "device-events",
|
|
79509
|
+
"device-attention-resolved": "device-events",
|
|
79493
79510
|
"node-online": "system",
|
|
79494
79511
|
"node-offline": "system",
|
|
79495
79512
|
"node-restarting": "system",
|
|
@@ -79572,6 +79589,12 @@ var NC_SYSTEM_EVENT_KIND_GROUP_SPECS = [
|
|
|
79572
79589
|
label: "Detecting nothing",
|
|
79573
79590
|
kinds: ["detection-blind"]
|
|
79574
79591
|
},
|
|
79592
|
+
{
|
|
79593
|
+
id: "motion-noise",
|
|
79594
|
+
family: "device-events",
|
|
79595
|
+
label: "Motion without a subject",
|
|
79596
|
+
kinds: ["motion-noisy", "motion-calm"]
|
|
79597
|
+
},
|
|
79575
79598
|
{
|
|
79576
79599
|
id: "recording",
|
|
79577
79600
|
family: "device-events",
|
|
@@ -79582,6 +79605,12 @@ var NC_SYSTEM_EVENT_KIND_GROUP_SPECS = [
|
|
|
79582
79605
|
"recording-degraded"
|
|
79583
79606
|
]
|
|
79584
79607
|
},
|
|
79608
|
+
{
|
|
79609
|
+
id: "device-attention",
|
|
79610
|
+
family: "device-events",
|
|
79611
|
+
label: "Needs attention",
|
|
79612
|
+
kinds: ["device-attention-required", "device-attention-resolved"]
|
|
79613
|
+
},
|
|
79585
79614
|
{
|
|
79586
79615
|
id: "nodes",
|
|
79587
79616
|
family: "system",
|
|
@@ -79721,6 +79750,7 @@ var ALERT_EPISODE = [
|
|
|
79721
79750
|
"alert-error",
|
|
79722
79751
|
"alert-critical-resolved"
|
|
79723
79752
|
];
|
|
79753
|
+
var DEVICE_ATTENTION = ["device-attention-required", "device-attention-resolved"];
|
|
79724
79754
|
var UPDATES = [
|
|
79725
79755
|
"addon-update-available",
|
|
79726
79756
|
"server-update-available",
|
|
@@ -79750,9 +79780,12 @@ var DEVICE_EVENTS = [
|
|
|
79750
79780
|
"stream-online",
|
|
79751
79781
|
"stream-offline",
|
|
79752
79782
|
"detection-blind",
|
|
79783
|
+
"motion-noisy",
|
|
79784
|
+
"motion-calm",
|
|
79753
79785
|
"recording-stalled",
|
|
79754
79786
|
"recording-healthy",
|
|
79755
79787
|
"recording-degraded",
|
|
79788
|
+
...DEVICE_ATTENTION,
|
|
79756
79789
|
...ALARM
|
|
79757
79790
|
];
|
|
79758
79791
|
/** Every kind a summary may speak about — the two summarisable families. */
|
|
@@ -79920,7 +79953,9 @@ var STATE_SUMMARY_VARS = [
|
|
|
79920
79953
|
[...RULE_TEXT],
|
|
79921
79954
|
[...RULE_TEXT],
|
|
79922
79955
|
[...RULE_TEXT],
|
|
79923
|
-
|
|
79956
|
+
[...RULE_TEXT],
|
|
79957
|
+
[...RULE_TEXT],
|
|
79958
|
+
([...RULE_TEXT], [...DEVICE_ATTENTION, ...ALERT_EPISODE]),
|
|
79924
79959
|
[...RULE_TEXT],
|
|
79925
79960
|
[...RULE_TEXT],
|
|
79926
79961
|
[...RULE_TEXT],
|
|
@@ -79942,11 +79977,11 @@ var STATE_SUMMARY_VARS = [
|
|
|
79942
79977
|
[...RULE_TEXT],
|
|
79943
79978
|
[...RULE_TEXT],
|
|
79944
79979
|
[...RULE_TEXT],
|
|
79980
|
+
([...RULE_TEXT], [...DEVICE_ATTENTION, ...ALERT_EPISODE]),
|
|
79945
79981
|
([...RULE_TEXT], [...ALERT_EPISODE]),
|
|
79982
|
+
([...RULE_TEXT], [...DEVICE_ATTENTION, ...ALERT_EPISODE]),
|
|
79946
79983
|
([...RULE_TEXT], [...ALERT_EPISODE]),
|
|
79947
|
-
([...RULE_TEXT], [...ALERT_EPISODE]),
|
|
79948
|
-
([...RULE_TEXT], [...ALERT_EPISODE]),
|
|
79949
|
-
([...RULE_TEXT], [...ALERT_EPISODE]),
|
|
79984
|
+
([...RULE_TEXT], [...DEVICE_ATTENTION, ...ALERT_EPISODE]),
|
|
79950
79985
|
[...RULE_TEXT],
|
|
79951
79986
|
[...RULE_TEXT],
|
|
79952
79987
|
[...RULE_TEXT],
|
|
@@ -80022,6 +80057,15 @@ new Map([
|
|
|
80022
80057
|
snapshotLabel: "Tanks low or full now",
|
|
80023
80058
|
snapshotSection: "tanks"
|
|
80024
80059
|
},
|
|
80060
|
+
{
|
|
80061
|
+
id: "motion-noise",
|
|
80062
|
+
family: "device-events",
|
|
80063
|
+
label: "Motion without a subject (constant / calm again)",
|
|
80064
|
+
bad: ["motion-noisy"],
|
|
80065
|
+
recovery: ["motion-calm"],
|
|
80066
|
+
snapshotLabel: "Cameras with constant motion now",
|
|
80067
|
+
snapshotSection: null
|
|
80068
|
+
},
|
|
80025
80069
|
{
|
|
80026
80070
|
id: "recording-health",
|
|
80027
80071
|
family: "device-events",
|
|
@@ -80031,6 +80075,15 @@ new Map([
|
|
|
80031
80075
|
snapshotLabel: "Recordings stalled now",
|
|
80032
80076
|
snapshotSection: null
|
|
80033
80077
|
},
|
|
80078
|
+
{
|
|
80079
|
+
id: "device-attention",
|
|
80080
|
+
family: "device-events",
|
|
80081
|
+
label: "Device needs attention (raised / resolved)",
|
|
80082
|
+
bad: ["device-attention-required"],
|
|
80083
|
+
recovery: ["device-attention-resolved"],
|
|
80084
|
+
snapshotLabel: "Devices needing attention now",
|
|
80085
|
+
snapshotSection: null
|
|
80086
|
+
},
|
|
80034
80087
|
{
|
|
80035
80088
|
id: "node-connectivity",
|
|
80036
80089
|
family: "system",
|
|
@@ -80667,7 +80720,7 @@ function buildConnectionFormSchema() {
|
|
|
80667
80720
|
id: "credentials",
|
|
80668
80721
|
title: "Tuya IoT cloud project",
|
|
80669
80722
|
titleKey: "provider-tuya:connection.s_credentials.title",
|
|
80670
|
-
description: "Create a
|
|
80723
|
+
description: "Create a project at iot.tuya.com, link your Smart Life / Tuya account to it, and paste its Access ID and Access Secret.",
|
|
80671
80724
|
descriptionKey: "provider-tuya:connection.s_credentials.description",
|
|
80672
80725
|
columns: 1,
|
|
80673
80726
|
fields: [{
|
package/dist/addon.mjs
CHANGED
|
@@ -818,7 +818,7 @@ async function discoverDevices(options = {}, binder = createDgramBinder()) {
|
|
|
818
818
|
return [...byId.values()];
|
|
819
819
|
}
|
|
820
820
|
//#endregion
|
|
821
|
-
//#region ../types/dist/event-category-
|
|
821
|
+
//#region ../types/dist/event-category-BfJwUd2S.mjs
|
|
822
822
|
var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
823
823
|
EventCategory["SystemBoot"] = "system.boot";
|
|
824
824
|
EventCategory["SystemAddonsReady"] = "system.addons-ready";
|
|
@@ -1135,6 +1135,15 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
|
1135
1135
|
*/
|
|
1136
1136
|
EventCategory["PipelineDetectionBlind"] = "pipeline.detection-blind";
|
|
1137
1137
|
/**
|
|
1138
|
+
* A camera's motion source has fired constantly with no subject for an hour
|
|
1139
|
+
* (motion duty or session count over the bar, zero detections) — it is not
|
|
1140
|
+
* blind, its motion zones or sensitivity want tuning (D907). Paired with
|
|
1141
|
+
* {@link PipelineMotionCalm}.
|
|
1142
|
+
*/
|
|
1143
|
+
EventCategory["PipelineMotionNoisy"] = "pipeline.motion-noisy";
|
|
1144
|
+
/** The recovery edge of {@link PipelineMotionNoisy}: the motion fell back, or a detection arrived. */
|
|
1145
|
+
EventCategory["PipelineMotionCalm"] = "pipeline.motion-calm";
|
|
1146
|
+
/**
|
|
1138
1147
|
* Per-camera pipeline config was mutated by the orchestrator
|
|
1139
1148
|
* (3-level settings change via `setAgentAddonDefaults` /
|
|
1140
1149
|
* `setCameraStepToggle` / `setCameraPipelineForAgent` or a
|
|
@@ -6241,7 +6250,7 @@ var ZodIssueCode = {
|
|
|
6241
6250
|
var ZodFirstPartyTypeKind;
|
|
6242
6251
|
ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
|
|
6243
6252
|
//#endregion
|
|
6244
|
-
//#region ../types/dist/sleep-
|
|
6253
|
+
//#region ../types/dist/sleep-DJFUfKvA.mjs
|
|
6245
6254
|
/**
|
|
6246
6255
|
* The audio chunk plane's byte format, and the ONE expansion from a coded
|
|
6247
6256
|
* window to float samples (D455).
|
|
@@ -8770,7 +8779,7 @@ var EntryDescriptorSchema = object({
|
|
|
8770
8779
|
/** JSON Schema of the entry body; `secret: true` marks a password field. */
|
|
8771
8780
|
fields: record(string(), unknown())
|
|
8772
8781
|
}).strict();
|
|
8773
|
-
/** What crosses the wire
|
|
8782
|
+
/** What crosses the wire from an addon: JSON only, no Zod. An unknown key is refused. */
|
|
8774
8783
|
var RecordKindDeclarationSchema = object({
|
|
8775
8784
|
database: _enum(RECORD_DATABASES).default("settings"),
|
|
8776
8785
|
class: _enum(RECORD_CLASSES),
|
|
@@ -8789,14 +8798,6 @@ var RecordKindDeclarationSchema = object({
|
|
|
8789
8798
|
secretPaths: array(string().min(1)).default([]),
|
|
8790
8799
|
/** The id key of each array that carries a secret (`{ headers: 'name' }`). */
|
|
8791
8800
|
secretArrayKeys: record(string(), string()).default({}),
|
|
8792
|
-
/**
|
|
8793
|
-
* RETIRED (D900): the legacy table a kind adopted from during the records
|
|
8794
|
-
* migration. Nothing declares it any more and nothing reads it; the schema
|
|
8795
|
-
* still ACCEPTS it because the catalog rows the migration wrote carry it
|
|
8796
|
-
* (an orphaned kind is never redeclared) and an addon built before the
|
|
8797
|
-
* removal still sends it. Never set it.
|
|
8798
|
-
*/
|
|
8799
|
-
adoptsFrom: string().min(1).optional(),
|
|
8800
8801
|
/** Kinds that must agree through `transact` sit in one file under one family name. */
|
|
8801
8802
|
transactFamily: string().min(1).optional(),
|
|
8802
8803
|
entry: EntryDescriptorSchema.optional()
|
|
@@ -13474,17 +13475,6 @@ object({
|
|
|
13474
13475
|
createdAt: number(),
|
|
13475
13476
|
updatedAt: number()
|
|
13476
13477
|
});
|
|
13477
|
-
object({
|
|
13478
|
-
id: string(),
|
|
13479
|
-
label: string(),
|
|
13480
|
-
isAdmin: boolean().default(false),
|
|
13481
|
-
allowedProviders: AllowedProviderSchema,
|
|
13482
|
-
allowedDevices: AllowedDevicesSchema,
|
|
13483
|
-
tokenHash: string(),
|
|
13484
|
-
tokenPrefix: string(),
|
|
13485
|
-
createdAt: number(),
|
|
13486
|
-
lastUsedAt: number().optional()
|
|
13487
|
-
});
|
|
13488
13478
|
object({
|
|
13489
13479
|
id: string(),
|
|
13490
13480
|
userId: string(),
|
|
@@ -17466,16 +17456,36 @@ var RecordKindStateSchema = _enum([
|
|
|
17466
17456
|
var DeclareKindResultSchema = object({
|
|
17467
17457
|
kindId: number().int(),
|
|
17468
17458
|
state: RecordKindStateSchema,
|
|
17469
|
-
createdIndexes: array(string())
|
|
17470
|
-
/**
|
|
17471
|
-
* RETIRED (D900): always `null`. It carried the records-migration boot guard;
|
|
17472
|
-
* it stays on the wire, null, because an addon built before the removal reads
|
|
17473
|
-
* an ABSENT field as "adoption pending" and refuses to start.
|
|
17474
|
-
*/
|
|
17475
|
-
adoptionPending: _null()
|
|
17459
|
+
createdIndexes: array(string())
|
|
17476
17460
|
});
|
|
17477
17461
|
/** Keychain refs a write released (the old marker is gone from the row): the owner deletes the values. */
|
|
17478
17462
|
var SecretRefsList = array(string());
|
|
17463
|
+
/**
|
|
17464
|
+
* One op of a `transact`: the single-row writes, each on a kind of the caller.
|
|
17465
|
+
* All ops of one call share ONE database file and ONE `transactFamily`.
|
|
17466
|
+
*/
|
|
17467
|
+
var RecordTransactOpSchema = discriminatedUnion("op", [
|
|
17468
|
+
object({
|
|
17469
|
+
op: literal("put"),
|
|
17470
|
+
kind: RecordKindNameSchema,
|
|
17471
|
+
record: RecordInputSchema,
|
|
17472
|
+
ifRev: number().int().min(0).optional()
|
|
17473
|
+
}),
|
|
17474
|
+
object({
|
|
17475
|
+
op: literal("patch"),
|
|
17476
|
+
kind: RecordKindNameSchema,
|
|
17477
|
+
id: RecordIdSchema,
|
|
17478
|
+
data: RecordBodySchema,
|
|
17479
|
+
at: number().int().nullable().optional(),
|
|
17480
|
+
expiresAt: number().int().nullable().optional(),
|
|
17481
|
+
ifRev: number().int().min(1).optional()
|
|
17482
|
+
}),
|
|
17483
|
+
object({
|
|
17484
|
+
op: literal("delete"),
|
|
17485
|
+
kind: RecordKindNameSchema,
|
|
17486
|
+
id: RecordIdSchema
|
|
17487
|
+
})
|
|
17488
|
+
]);
|
|
17479
17489
|
var RecordSecretRefsSchema = record(string(), record(string(), string()));
|
|
17480
17490
|
method(object({ kinds: record(RecordKindNameSchema, RecordKindDeclarationSchema) }), object({ kinds: record(string(), DeclareKindResultSchema) }), {
|
|
17481
17491
|
kind: "mutation",
|
|
@@ -17582,6 +17592,16 @@ method(object({ kinds: record(RecordKindNameSchema, RecordKindDeclarationSchema)
|
|
|
17582
17592
|
}), {
|
|
17583
17593
|
kind: "mutation",
|
|
17584
17594
|
auth: "admin"
|
|
17595
|
+
}), method(object({ ops: array(RecordTransactOpSchema).min(1).max(RECORD_BATCH_MAX) }), object({
|
|
17596
|
+
results: array(object({
|
|
17597
|
+
rev: number().int().nullable(),
|
|
17598
|
+
deleted: boolean()
|
|
17599
|
+
})),
|
|
17600
|
+
releasedRefs: SecretRefsList,
|
|
17601
|
+
secretRefs: SecretRefsList
|
|
17602
|
+
}), {
|
|
17603
|
+
kind: "mutation",
|
|
17604
|
+
auth: "admin"
|
|
17585
17605
|
}), method(object({
|
|
17586
17606
|
deviceId: number().int(),
|
|
17587
17607
|
kinds: array(RecordKindNameSchema).optional()
|
|
@@ -43193,9 +43213,13 @@ var NcSystemEventKindSchema = _enum([
|
|
|
43193
43213
|
"node-updating",
|
|
43194
43214
|
"node-inference-unavailable",
|
|
43195
43215
|
"detection-blind",
|
|
43216
|
+
"motion-noisy",
|
|
43217
|
+
"motion-calm",
|
|
43196
43218
|
"recording-stalled",
|
|
43197
43219
|
"recording-healthy",
|
|
43198
43220
|
"recording-degraded",
|
|
43221
|
+
"device-attention-required",
|
|
43222
|
+
"device-attention-resolved",
|
|
43199
43223
|
"storage-location-low",
|
|
43200
43224
|
"storage-location-critical",
|
|
43201
43225
|
"storage-location-ok",
|
|
@@ -56527,6 +56551,16 @@ var DishwasherStatusSchema = object({
|
|
|
56527
56551
|
powerState: string().nullable(),
|
|
56528
56552
|
saltLevel: DishwasherConsumableLevelSchema.nullable(),
|
|
56529
56553
|
rinseAidLevel: DishwasherConsumableLevelSchema.nullable(),
|
|
56554
|
+
/**
|
|
56555
|
+
* True while the appliance asks for its filter to be cleaned (smart-filter, filter-system or
|
|
56556
|
+
* combined care-and-filter reminder raised); false when every such reminder reads clear; null
|
|
56557
|
+
* when none is reported. A cleared reminder is not an unknown one.
|
|
56558
|
+
*/
|
|
56559
|
+
filterCleaningDue: boolean().nullable(),
|
|
56560
|
+
/** True while the machine-care (descaling / cleaning-program) reminder is raised; false when clear; null when not reported. */
|
|
56561
|
+
machineCareDue: boolean().nullable(),
|
|
56562
|
+
/** Program runs left before the machine-care reminder is due; null when the appliance does not say. */
|
|
56563
|
+
machineCareRemainingRuns: number().int().nonnegative().nullable(),
|
|
56530
56564
|
/** Option states: null when the appliance does not expose the option or has not said. */
|
|
56531
56565
|
halfLoad: boolean().nullable(),
|
|
56532
56566
|
hygienePlus: boolean().nullable(),
|
|
@@ -65177,16 +65211,6 @@ var UpdateUserInputSchema = object({
|
|
|
65177
65211
|
allowedDevices: record(string(), union([array(string()), literal("*")])).optional(),
|
|
65178
65212
|
scopes: array(TokenScopeSchema).optional()
|
|
65179
65213
|
});
|
|
65180
|
-
var ApiKeySummarySchema = object({
|
|
65181
|
-
id: string(),
|
|
65182
|
-
label: string(),
|
|
65183
|
-
isAdmin: boolean().default(false),
|
|
65184
|
-
allowedProviders: union([array(string()), literal("*")]).optional(),
|
|
65185
|
-
allowedDevices: record(string(), union([array(string()), literal("*")])).optional(),
|
|
65186
|
-
tokenPrefix: string(),
|
|
65187
|
-
createdAt: number(),
|
|
65188
|
-
lastUsedAt: number().optional()
|
|
65189
|
-
});
|
|
65190
65214
|
var OauthSessionSummarySchema = object({
|
|
65191
65215
|
id: string(),
|
|
65192
65216
|
userId: string(),
|
|
@@ -65208,8 +65232,7 @@ var TotpStatusSchema = object({
|
|
|
65208
65232
|
confirmedAt: number().nullable()
|
|
65209
65233
|
});
|
|
65210
65234
|
/**
|
|
65211
|
-
* user-management — singleton capability for user accounts
|
|
65212
|
-
* legacy API-key rows.
|
|
65235
|
+
* user-management — singleton capability for user accounts.
|
|
65213
65236
|
*
|
|
65214
65237
|
* v2 model: every method gated by `auth: 'admin'`. Admin-only delegation
|
|
65215
65238
|
* — the subset check on `setUserScopes` is moot
|
|
@@ -65265,10 +65288,6 @@ method(_void(), array(UserSummarySchema), { auth: "admin" }), method(CreateUserI
|
|
|
65265
65288
|
}), UserSummarySchema.extend({ passwordHash: string() }).nullable(), {
|
|
65266
65289
|
kind: "mutation",
|
|
65267
65290
|
access: "view"
|
|
65268
|
-
}), method(_void(), array(ApiKeySummarySchema), { auth: "admin" }), method(object({ id: string() }), object({ success: literal(true) }), {
|
|
65269
|
-
kind: "mutation",
|
|
65270
|
-
auth: "admin",
|
|
65271
|
-
access: "delete"
|
|
65272
65291
|
}), method(object({ userId: string() }), TotpSetupResultSchema, {
|
|
65273
65292
|
kind: "mutation",
|
|
65274
65293
|
auth: "admin",
|
|
@@ -74724,6 +74743,12 @@ Object.freeze({
|
|
|
74724
74743
|
addonId: null,
|
|
74725
74744
|
access: "view"
|
|
74726
74745
|
},
|
|
74746
|
+
"records.transact": {
|
|
74747
|
+
capName: "records",
|
|
74748
|
+
capScope: "system",
|
|
74749
|
+
addonId: null,
|
|
74750
|
+
access: "create"
|
|
74751
|
+
},
|
|
74727
74752
|
"sceneMonitor.captureReference": {
|
|
74728
74753
|
capName: "scene-monitor",
|
|
74729
74754
|
capScope: "device",
|
|
@@ -76056,12 +76081,6 @@ Object.freeze({
|
|
|
76056
76081
|
addonId: null,
|
|
76057
76082
|
access: "view"
|
|
76058
76083
|
},
|
|
76059
|
-
"userManagement.listApiKeys": {
|
|
76060
|
-
capName: "user-management",
|
|
76061
|
-
capScope: "system",
|
|
76062
|
-
addonId: null,
|
|
76063
|
-
access: "view"
|
|
76064
|
-
},
|
|
76065
76084
|
"userManagement.listExternalIdentities": {
|
|
76066
76085
|
capName: "user-management",
|
|
76067
76086
|
capScope: "system",
|
|
@@ -76116,12 +76135,6 @@ Object.freeze({
|
|
|
76116
76135
|
addonId: null,
|
|
76117
76136
|
access: "create"
|
|
76118
76137
|
},
|
|
76119
|
-
"userManagement.revokeApiKey": {
|
|
76120
|
-
capName: "user-management",
|
|
76121
|
-
capScope: "system",
|
|
76122
|
-
addonId: null,
|
|
76123
|
-
access: "delete"
|
|
76124
|
-
},
|
|
76125
76138
|
"userManagement.revokeOauthSession": {
|
|
76126
76139
|
capName: "user-management",
|
|
76127
76140
|
capScope: "system",
|
|
@@ -79486,9 +79499,13 @@ new Map(Object.entries({
|
|
|
79486
79499
|
"stream-online": "device-events",
|
|
79487
79500
|
"stream-offline": "device-events",
|
|
79488
79501
|
"detection-blind": "device-events",
|
|
79502
|
+
"motion-noisy": "device-events",
|
|
79503
|
+
"motion-calm": "device-events",
|
|
79489
79504
|
"recording-stalled": "device-events",
|
|
79490
79505
|
"recording-healthy": "device-events",
|
|
79491
79506
|
"recording-degraded": "device-events",
|
|
79507
|
+
"device-attention-required": "device-events",
|
|
79508
|
+
"device-attention-resolved": "device-events",
|
|
79492
79509
|
"node-online": "system",
|
|
79493
79510
|
"node-offline": "system",
|
|
79494
79511
|
"node-restarting": "system",
|
|
@@ -79571,6 +79588,12 @@ var NC_SYSTEM_EVENT_KIND_GROUP_SPECS = [
|
|
|
79571
79588
|
label: "Detecting nothing",
|
|
79572
79589
|
kinds: ["detection-blind"]
|
|
79573
79590
|
},
|
|
79591
|
+
{
|
|
79592
|
+
id: "motion-noise",
|
|
79593
|
+
family: "device-events",
|
|
79594
|
+
label: "Motion without a subject",
|
|
79595
|
+
kinds: ["motion-noisy", "motion-calm"]
|
|
79596
|
+
},
|
|
79574
79597
|
{
|
|
79575
79598
|
id: "recording",
|
|
79576
79599
|
family: "device-events",
|
|
@@ -79581,6 +79604,12 @@ var NC_SYSTEM_EVENT_KIND_GROUP_SPECS = [
|
|
|
79581
79604
|
"recording-degraded"
|
|
79582
79605
|
]
|
|
79583
79606
|
},
|
|
79607
|
+
{
|
|
79608
|
+
id: "device-attention",
|
|
79609
|
+
family: "device-events",
|
|
79610
|
+
label: "Needs attention",
|
|
79611
|
+
kinds: ["device-attention-required", "device-attention-resolved"]
|
|
79612
|
+
},
|
|
79584
79613
|
{
|
|
79585
79614
|
id: "nodes",
|
|
79586
79615
|
family: "system",
|
|
@@ -79720,6 +79749,7 @@ var ALERT_EPISODE = [
|
|
|
79720
79749
|
"alert-error",
|
|
79721
79750
|
"alert-critical-resolved"
|
|
79722
79751
|
];
|
|
79752
|
+
var DEVICE_ATTENTION = ["device-attention-required", "device-attention-resolved"];
|
|
79723
79753
|
var UPDATES = [
|
|
79724
79754
|
"addon-update-available",
|
|
79725
79755
|
"server-update-available",
|
|
@@ -79749,9 +79779,12 @@ var DEVICE_EVENTS = [
|
|
|
79749
79779
|
"stream-online",
|
|
79750
79780
|
"stream-offline",
|
|
79751
79781
|
"detection-blind",
|
|
79782
|
+
"motion-noisy",
|
|
79783
|
+
"motion-calm",
|
|
79752
79784
|
"recording-stalled",
|
|
79753
79785
|
"recording-healthy",
|
|
79754
79786
|
"recording-degraded",
|
|
79787
|
+
...DEVICE_ATTENTION,
|
|
79755
79788
|
...ALARM
|
|
79756
79789
|
];
|
|
79757
79790
|
/** Every kind a summary may speak about — the two summarisable families. */
|
|
@@ -79919,7 +79952,9 @@ var STATE_SUMMARY_VARS = [
|
|
|
79919
79952
|
[...RULE_TEXT],
|
|
79920
79953
|
[...RULE_TEXT],
|
|
79921
79954
|
[...RULE_TEXT],
|
|
79922
|
-
|
|
79955
|
+
[...RULE_TEXT],
|
|
79956
|
+
[...RULE_TEXT],
|
|
79957
|
+
([...RULE_TEXT], [...DEVICE_ATTENTION, ...ALERT_EPISODE]),
|
|
79923
79958
|
[...RULE_TEXT],
|
|
79924
79959
|
[...RULE_TEXT],
|
|
79925
79960
|
[...RULE_TEXT],
|
|
@@ -79941,11 +79976,11 @@ var STATE_SUMMARY_VARS = [
|
|
|
79941
79976
|
[...RULE_TEXT],
|
|
79942
79977
|
[...RULE_TEXT],
|
|
79943
79978
|
[...RULE_TEXT],
|
|
79979
|
+
([...RULE_TEXT], [...DEVICE_ATTENTION, ...ALERT_EPISODE]),
|
|
79944
79980
|
([...RULE_TEXT], [...ALERT_EPISODE]),
|
|
79981
|
+
([...RULE_TEXT], [...DEVICE_ATTENTION, ...ALERT_EPISODE]),
|
|
79945
79982
|
([...RULE_TEXT], [...ALERT_EPISODE]),
|
|
79946
|
-
([...RULE_TEXT], [...ALERT_EPISODE]),
|
|
79947
|
-
([...RULE_TEXT], [...ALERT_EPISODE]),
|
|
79948
|
-
([...RULE_TEXT], [...ALERT_EPISODE]),
|
|
79983
|
+
([...RULE_TEXT], [...DEVICE_ATTENTION, ...ALERT_EPISODE]),
|
|
79949
79984
|
[...RULE_TEXT],
|
|
79950
79985
|
[...RULE_TEXT],
|
|
79951
79986
|
[...RULE_TEXT],
|
|
@@ -80021,6 +80056,15 @@ new Map([
|
|
|
80021
80056
|
snapshotLabel: "Tanks low or full now",
|
|
80022
80057
|
snapshotSection: "tanks"
|
|
80023
80058
|
},
|
|
80059
|
+
{
|
|
80060
|
+
id: "motion-noise",
|
|
80061
|
+
family: "device-events",
|
|
80062
|
+
label: "Motion without a subject (constant / calm again)",
|
|
80063
|
+
bad: ["motion-noisy"],
|
|
80064
|
+
recovery: ["motion-calm"],
|
|
80065
|
+
snapshotLabel: "Cameras with constant motion now",
|
|
80066
|
+
snapshotSection: null
|
|
80067
|
+
},
|
|
80024
80068
|
{
|
|
80025
80069
|
id: "recording-health",
|
|
80026
80070
|
family: "device-events",
|
|
@@ -80030,6 +80074,15 @@ new Map([
|
|
|
80030
80074
|
snapshotLabel: "Recordings stalled now",
|
|
80031
80075
|
snapshotSection: null
|
|
80032
80076
|
},
|
|
80077
|
+
{
|
|
80078
|
+
id: "device-attention",
|
|
80079
|
+
family: "device-events",
|
|
80080
|
+
label: "Device needs attention (raised / resolved)",
|
|
80081
|
+
bad: ["device-attention-required"],
|
|
80082
|
+
recovery: ["device-attention-resolved"],
|
|
80083
|
+
snapshotLabel: "Devices needing attention now",
|
|
80084
|
+
snapshotSection: null
|
|
80085
|
+
},
|
|
80033
80086
|
{
|
|
80034
80087
|
id: "node-connectivity",
|
|
80035
80088
|
family: "system",
|
|
@@ -80666,7 +80719,7 @@ function buildConnectionFormSchema() {
|
|
|
80666
80719
|
id: "credentials",
|
|
80667
80720
|
title: "Tuya IoT cloud project",
|
|
80668
80721
|
titleKey: "provider-tuya:connection.s_credentials.title",
|
|
80669
|
-
description: "Create a
|
|
80722
|
+
description: "Create a project at iot.tuya.com, link your Smart Life / Tuya account to it, and paste its Access ID and Access Secret.",
|
|
80670
80723
|
descriptionKey: "provider-tuya:connection.s_credentials.description",
|
|
80671
80724
|
columns: 1,
|
|
80672
80725
|
fields: [{
|
package/i18n/en.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"connection.s_credentials.title": "Tuya IoT cloud project",
|
|
3
|
-
"connection.s_credentials.description": "Create a
|
|
3
|
+
"connection.s_credentials.description": "Create a project at iot.tuya.com, link your Smart Life / Tuya account to it, and paste its Access ID and Access Secret.",
|
|
4
4
|
"connection.s_credentials.accessId.label": "Access ID / Client ID",
|
|
5
5
|
"connection.s_credentials.accessSecret.label": "Access Secret / Client Secret",
|
|
6
6
|
"connection.s_region.title": "Region",
|
package/i18n/it.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"connection.s_credentials.title": "Progetto cloud Tuya IoT",
|
|
3
|
-
"connection.s_credentials.description": "Crea un progetto
|
|
3
|
+
"connection.s_credentials.description": "Crea un progetto su iot.tuya.com, collega il tuo account Smart Life / Tuya e incolla Access ID e Access Secret.",
|
|
4
4
|
"connection.s_credentials.accessId.label": "Access ID / Client ID",
|
|
5
5
|
"connection.s_credentials.accessSecret.label": "Access Secret / Client Secret",
|
|
6
6
|
"connection.s_region.title": "Regione",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@camstack/addon-provider-tuya",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.141",
|
|
4
4
|
"description": "Tuya / Smart Life device-provider addon for CamStack — account-onboarded (Tuya IoT cloud fetch of device localKeys) + LOCAL DP control via the @apocaliss92/nodetuya encrypted-LAN client, exposing switch / water-heater-family kettle entities",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"camstack",
|