@mega-yfue/eufy-sdk 0.6.0-beta.43 → 0.6.0-beta.45

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/index.js CHANGED
@@ -3462,7 +3462,7 @@ function propertiesOf(members, ctx) {
3462
3462
  // stored value is that payload — see `PropertySpec.raw`.
3463
3463
  raw: m.decode ? true : void 0,
3464
3464
  readAliases: aliases?.slice(promoted ? 1 : 0).map(({ paramType, invert }) => ({ paramType, invert })),
3465
- writable: m.write !== void 0 || m.writtenElsewhere === true,
3465
+ writable: m.write !== void 0 && !(ctx && m.unverifiedFor?.(ctx)) || m.writtenElsewhere === true,
3466
3466
  reported: ctx?.paramIds ? wasReported(m, borrowedBy(m, members), { ...ctx, paramIds: ctx.paramIds }) : void 0,
3467
3467
  description: m.description
3468
3468
  }
@@ -3635,7 +3635,7 @@ function bindMembers(members, deps) {
3635
3635
  const get = decode ? () => decode(raw(), rawDp2, ctx) : () => narrow(m.type, read, prop, domain);
3636
3636
  Object.defineProperty(out, name, { get, enumerable: true, configurable: true });
3637
3637
  }
3638
- if (!m.write || m.unverified || !installs(m, ctx) || !writeRoutable(m, ctx))
3638
+ if (!m.write || m.unverified || m.unverifiedFor?.(ctx) || !installs(m, ctx) || !writeRoutable(m, ctx))
3639
3639
  continue;
3640
3640
  if (m.writeOnly)
3641
3641
  unobservable.push(name);
@@ -3736,6 +3736,9 @@ function holds(claim, installed, ctx) {
3736
3736
  return false;
3737
3737
  if (claim.reads?.some((name) => !installed.has(name)))
3738
3738
  return false;
3739
+ const things = ctx?.things;
3740
+ if (claim.things && things && !claim.things.some((id) => things.properties[id]))
3741
+ return false;
3739
3742
  if (claim.homeBaseAttached !== void 0 && ctx?.homeBaseAttached !== void 0) {
3740
3743
  return ctx.homeBaseAttached === claim.homeBaseAttached;
3741
3744
  }
@@ -4668,8 +4671,6 @@ var MOTION = {
4668
4671
  events: [
4669
4672
  { source: "push", match: DoorbellPushEvent.MOTION_DETECTION, emit: "motion" },
4670
4673
  { source: "push", match: CusPushEvent.MOTION_SENSOR_PIR, emit: "motion" },
4671
- { source: "push", match: IndoorPushEvent.CRYING_DETECTION, emit: "cryingDetected", claim: CAMERA_AI_CLAIM },
4672
- { source: "push", match: IndoorPushEvent.SOUND_DETECTION, emit: "soundDetected", claim: CAMERA_AI_CLAIM },
4673
4674
  { source: "push", match: IndoorPushEvent.PET_DETECTION, emit: "petDetection", claim: CAMERA_AI_CLAIM },
4674
4675
  { source: "push", match: DoorbellPushEvent.VEHICLE_DETECTION, emit: "vehicleDetected", claim: VEHICLE_CLAIM },
4675
4676
  { source: "push", match: HB3PairedDevicePushEvent.DOG_DETECTION, emit: "dogDetected", claim: DOG_CLAIM },
@@ -6532,6 +6533,21 @@ var CAMERA = {
6532
6533
  properties: propertiesOf(CAMERA_MEMBERS),
6533
6534
  /** Every camera-codec device has the power/privacy surface. */
6534
6535
  detection: { codecs: ["camera"] },
6536
+ /** The sound (3105) and crying (3104) pushes, each claimed on the product's thing property for it. */
6537
+ events: [
6538
+ {
6539
+ source: "push",
6540
+ match: IndoorPushEvent.SOUND_DETECTION,
6541
+ emit: "soundDetected",
6542
+ claim: { things: ["sound_detection_status", "sound_detection_type"] }
6543
+ },
6544
+ {
6545
+ source: "push",
6546
+ match: IndoorPushEvent.CRYING_DETECTION,
6547
+ emit: "cryingDetected",
6548
+ claim: { things: ["notification_ai_crying_switch", "sound_detection_type"] }
6549
+ }
6550
+ ],
6535
6551
  /** Only the no-argument power verbs, which carry no value for a member to hold. */
6536
6552
  actions({ ctx, sink }) {
6537
6553
  if (!isCameraCodec(ctx))
@@ -6865,25 +6881,12 @@ var LIGHT_SWITCH_INT_STRING_TYPES = /* @__PURE__ */ new Set([
6865
6881
  DeviceType.CAMERA3C,
6866
6882
  DeviceType.PROFESSIONAL_247
6867
6883
  ]);
6868
- function switchCommand(on, ctx) {
6869
- switch (lightSwitchWire(ctx)) {
6870
- case "json":
6871
- return setJson(LIGHT_CMD.FLOODLIGHT_SWITCH, { time: 0, type: 2, value: on ? 1 : 0 }, ctx);
6872
- case "int-string":
6873
- return setScalar(LIGHT_CMD.FLOODLIGHT_SWITCH, on ? 1 : 0, ctx, "int-string");
6874
- default:
6875
- return void 0;
6876
- }
6884
+ function switchCommand(on, wire, ctx) {
6885
+ return wire === "json" ? setJson(LIGHT_CMD.FLOODLIGHT_SWITCH, { time: 0, type: 2, value: on ? 1 : 0 }, ctx) : setScalar(LIGHT_CMD.FLOODLIGHT_SWITCH, on ? 1 : 0, ctx, "int-string");
6877
6886
  }
6878
6887
  function directBinary(param, value, ctx) {
6879
6888
  return setScalar(param, value, ctx, "direct-binary");
6880
6889
  }
6881
- function switchFrame(on, ctx) {
6882
- const cmd = switchCommand(on, ctx);
6883
- if (!cmd)
6884
- throw new Error(`light: unknown spotlight switch wire format \u2014 confirm it [${describeDevice(ctx)}]`);
6885
- return cmd;
6886
- }
6887
6890
  var LIGHT_MEMBERS = {
6888
6891
  /**
6889
6892
  * Whether the lamp is lit RIGHT NOW — the momentary switch, not a setting. Measured on a T8170: 1400
@@ -6894,9 +6897,8 @@ var LIGHT_MEMBERS = {
6894
6897
  * So it reads on whenever any client is watching. The setting a user changes and expects to persist
6895
6898
  * is {@link spotlightEnabled}.
6896
6899
  *
6897
- * The switch refuses for a reason a value check cannot give — this model's frame SHAPE is unconfirmed —
6898
- * so `switchFrame` throws that reason and `bindMembers` turns it into the rejection, rather than
6899
- * letting the generated "not a valid value" blame a boolean that was never the problem.
6900
+ * The switch frame SHAPE is per family ({@link lightSwitchWire}), and the write is `unverifiedFor` the
6901
+ * families it has no shape for.
6900
6902
  */
6901
6903
  isOn: {
6902
6904
  param: LIGHT_CMD.FLOODLIGHT_SWITCH,
@@ -6905,7 +6907,11 @@ var LIGHT_MEMBERS = {
6905
6907
  kind: "boolean",
6906
6908
  provenance: "verified",
6907
6909
  description: "Light on/off (1400) \u2014 lit right now, not a setting: it follows whichever client is streaming. Verified via P2P state readback (3/3); session-scoped behaviour measured live on a T8170.",
6908
- write: (v, ctx) => switchFrame(asBool(v), ctx),
6910
+ write: (v, ctx) => {
6911
+ const wire = lightSwitchWire(ctx);
6912
+ return wire && switchCommand(asBool(v), wire, ctx);
6913
+ },
6914
+ unverifiedFor: (ctx) => lightSwitchWire(ctx) === void 0,
6909
6915
  writeAs: "set",
6910
6916
  aliases: { on: true, off: false }
6911
6917
  },
@@ -6986,14 +6992,15 @@ var LIGHT = {
6986
6992
  * Only what the member table cannot express: `on`/`off` as no-argument verbs over the same wire as the
6987
6993
  * derived `set`, and the write-only auto-spotlight composite. The verbs stay UNDESCRIBED on purpose —
6988
6994
  * `set` is the method that takes the value, and describing all three would offer one state as three
6989
- * controls. `async` is what turns `switchFrame`'s throw into the rejection a `Promise<void>`
6990
- * caller expects, the same shape the derived setter gets from `bindMembers`.
6995
+ * controls. Like `set`, the verbs are absent on a model whose switch shape is unverified.
6991
6996
  */
6992
6997
  actions({ ctx, sink }) {
6993
- const dispatchSwitch = async (on) => sink.dispatch(switchFrame(on, ctx));
6998
+ const wire = lightSwitchWire(ctx);
6994
6999
  return {
6995
- on: () => dispatchSwitch(true),
6996
- off: () => dispatchSwitch(false),
7000
+ ...wire && {
7001
+ on: () => sink.dispatch(switchCommand(true, wire, ctx)),
7002
+ off: () => sink.dispatch(switchCommand(false, wire, ctx))
7003
+ },
6997
7004
  setAutoSpotlight: (on, opts) => sink.dispatch(autoSpotlightCommand(asBool(on), ctx, opts))
6998
7005
  };
6999
7006
  }
@@ -11862,8 +11869,8 @@ function memberCommand(m, action, value, ctx) {
11862
11869
  const claims = action === property2 || member.intentNames?.includes(action) === true;
11863
11870
  if (!claims && aliased === void 0)
11864
11871
  continue;
11865
- if (member.unverified) {
11866
- throw new Error(`${m.capability}: ${name} write wire unverified \u2014 confirm it on a device before sending`);
11872
+ if (member.unverified || member.unverifiedFor?.(ctx)) {
11873
+ throw new Error(`${m.capability}: ${name} write wire unverified \u2014 confirm it on a device before sending [${describeDevice(ctx)}]`);
11867
11874
  }
11868
11875
  if (!member.write || !installs(member, ctx))
11869
11876
  continue;
@@ -14061,6 +14068,8 @@ var Device = class _Device {
14061
14068
  * answers a caller has to be able to tell apart.
14062
14069
  */
14063
14070
  bound = false;
14071
+ /** The product's thing description resolved for this device, as {@link bindActions} was given it. */
14072
+ things;
14064
14073
  /**
14065
14074
  * Read-through freshness policy (injected by the facade via {@link setFreshnessPolicy}; the model
14066
14075
  * stays transport-free — it only calls the supplied `refresh`). Default: caching OFF
@@ -14158,6 +14167,7 @@ var Device = class _Device {
14158
14167
  ff09Settings,
14159
14168
  rawDp: rawDp2
14160
14169
  });
14170
+ this.things = ctx.things;
14161
14171
  this.bound = true;
14162
14172
  }
14163
14173
  /**
@@ -14373,7 +14383,8 @@ var Device = class _Device {
14373
14383
  model: this.model,
14374
14384
  capabilities: new Set(this.capabilities),
14375
14385
  homeBaseAttached: this.stationSn !== this.sn,
14376
- stationSerial: this.stationSn
14386
+ stationSerial: this.stationSn,
14387
+ things: this.things
14377
14388
  })
14378
14389
  };
14379
14390
  }