@mega-yfue/eufy-sdk 0.5.0-beta.74 → 0.5.0-beta.75

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
@@ -5619,6 +5619,7 @@ var CAMERA_MEMBERS = {
5619
5619
  type: "bool",
5620
5620
  kind: "boolean",
5621
5621
  provenance: "verified",
5622
+ available: isCameraCodec,
5622
5623
  invert: true,
5623
5624
  invertFor: (ctx) => isT8410HomeBase3(ctx) ? false : void 0,
5624
5625
  readAliases: [{ paramType: 2001, invert: false }],
@@ -5643,6 +5644,7 @@ var CAMERA_MEMBERS = {
5643
5644
  type: "bool",
5644
5645
  kind: "boolean",
5645
5646
  provenance: "apk",
5647
+ available: isCameraCodec,
5646
5648
  description: "Rotate the image 180\xB0 (ROTATE_IMAGE 1207): false = normal, true = flipped. For ceiling/upside-down mounts. Write is a direct param; wire from the app parser (unverified live).",
5647
5649
  write: (v, ctx) => setScalar(CAMERA_CMD.ROTATE_IMAGE, asBool(v) ? 1 : 0, ctx, "auto")
5648
5650
  },
@@ -5658,6 +5660,7 @@ var CAMERA_MEMBERS = {
5658
5660
  kind: "enum",
5659
5661
  enumValues: { 0: "Off", 1: "Timestamp", 2: "Timestamp + Logo" },
5660
5662
  provenance: "verified",
5663
+ available: isCameraCodec,
5661
5664
  description: "On-screen watermark/OSD overlay (CMD_SET_DEVS_OSD 1214). \u2705 wire verified live (T8425 ch3): direct-binary [ch][value 0/1/2] \u2014 a 3-value enum, not a bool. Enum labels are best-guess.",
5662
5665
  write: (v, ctx) => {
5663
5666
  const w = coerceEnumValue(Watermark, v);
@@ -5674,6 +5677,7 @@ var CAMERA_MEMBERS = {
5674
5677
  type: "bool",
5675
5678
  kind: "boolean",
5676
5679
  provenance: "verified",
5680
+ available: isCameraCodec,
5677
5681
  description: "Trigger on sound as well as motion (SOUND_DETECTION 6043). \u2705 Write confirmed live on a T8410 (mains, standalone, own channel): both directions sent through this member and read back on the cloud param, and the app's own frame captured byte-exact for the same body.",
5678
5682
  write: (v, ctx) => setJson(CAMERA_CMD.SOUND_DETECTION, { status: asBool(v) ? 1 : 0 }, ctx)
5679
5683
  },
@@ -5689,6 +5693,7 @@ var CAMERA_MEMBERS = {
5689
5693
  type: "number",
5690
5694
  kind: "scalar",
5691
5695
  provenance: "verified",
5696
+ available: isCameraCodec,
5692
5697
  description: "Sound-detection sensitivity: 1 = lowest, 3 = mid, 5 = highest (SOUND_DETECTION_SENSITIVITY 6044). \u2705 Write confirmed live on a T8410: 1 and 5 sent consecutively through this member and read back on the cloud param. 2 and 4 are the scale's shape, not observed values.",
5693
5698
  write: (v, ctx) => {
5694
5699
  const n = Number(v);
@@ -5708,6 +5713,7 @@ var CAMERA_MEMBERS = {
5708
5713
  kind: "enum",
5709
5714
  enumValues: { 1: "Crying", 2: "All Sound" },
5710
5715
  provenance: "verified",
5716
+ available: isCameraCodec,
5711
5717
  description: "Which sounds trigger a detection: crying alone, or any sound (SOUND_DETECTION_TYPE 6046). \u2705 Write confirmed live on a T8410: both values sent consecutively through this member and read back on the cloud param.",
5712
5718
  write: (v, ctx) => {
5713
5719
  const type = coerceEnumValue(SoundDetectionType, v);
@@ -5728,6 +5734,7 @@ var CAMERA_MEMBERS = {
5728
5734
  kind: "enum",
5729
5735
  enumValues: { 1: "Text Only", 2: "Included Thumbnail", 3: "Text First, Then Thumbnail" },
5730
5736
  provenance: "verified",
5737
+ available: isCameraCodec,
5731
5738
  description: "How much a detection push carries: text only, a thumbnail, or text then a thumbnail (CMD_INDOOR_PUSH_NOTIFY_TYPE 6020). All three values wire-verified live on a standalone T8171 over the cloud/WAN path \u2014 the 1700 control-payload wrapper, each one read back on the cloud param. A value outside the enum is REJECTED, not clamped: every neighbouring value is a real style, so a bad one would silently select the wrong notification.",
5732
5739
  write: (v, ctx) => {
5733
5740
  const style = coerceEnumValue(NotificationStyle2, v);
@@ -5746,6 +5753,7 @@ var CAMERA_MEMBERS = {
5746
5753
  kind: "enum",
5747
5754
  enumValues: { 0: "Off", 1: "Infrared", 2: "Full Color" },
5748
5755
  provenance: "verified",
5756
+ available: isCameraCodec,
5749
5757
  description: "Night-vision mode (NIGHT_VISION_TYPE 1277): 0 = off, 1 = infrared (B&W), 2 = full colour. \u2705 wire verified live (T8425 ch3): 1350 SET_PAYLOAD, mChannel 0, {channel:N, night_sion:mode}. Enum labels are best-guess. Some models omit full colour.",
5750
5758
  write: (v, ctx) => {
5751
5759
  const nv = coerceEnumValue(NightVision, v);
@@ -5771,6 +5779,7 @@ var CAMERA_MEMBERS = {
5771
5779
  kind: "enum",
5772
5780
  enumValues: STREAMING_QUALITY_TIERS,
5773
5781
  provenance: "verified",
5782
+ available: isCameraCodec,
5774
5783
  args: [{ name: "quality", kind: "enum", description: "A tier, or the name it maps to. 0 is Auto." }],
5775
5784
  ...accepts(),
5776
5785
  description: "Live-view quality as a tier, 0 = Auto (1020; the write rides 2730 APP_CMD_MULTI_CAM_SET_VIDEO_QUALITY). Distinct from recordingQuality, which is what gets stored. All four tiers wire-verified live on a T8170 and read back on 1020. Sent from this SDK to a standalone T8170 and T8171, tier 1 holds the live stream at 1280x720 and tier 0 restores the camera's own resolution ladder \u2014 see CAMERA_CMD.STREAMING_QUALITY_SET. A value outside the tier set is REJECTED, not clamped: every tier in range is a real quality, so a bad one would silently pick another.",
@@ -5788,6 +5797,7 @@ var CAMERA_MEMBERS = {
5788
5797
  param: CAMERA_CMD.RECORDING_QUALITY_SET,
5789
5798
  type: "string",
5790
5799
  provenance: "verified",
5800
+ available: isCameraCodec,
5791
5801
  decode: (raw) => decodeRecordingQualityTier(raw),
5792
5802
  decodedKind: "enum",
5793
5803
  decodedValues: Object.keys(RECORDING_QUALITY_TIERS).map(Number),
@@ -5812,6 +5822,7 @@ var CAMERA_MEMBERS = {
5812
5822
  type: "bool",
5813
5823
  kind: "boolean",
5814
5824
  provenance: "apk",
5825
+ available: isCameraCodec,
5815
5826
  description: "Anti-theft detection on/off (1015 APP_CMD_EAS_SWITCH; the app parses it as anti_theft_detection_switch). Adaptive scalar {value:0|1}. \u26A0\uFE0F Replay+readback confirmed on a HomeBase-attached T8425 only; standalone unverified and v3 devices use id 2735 \u2014 see CAMERA_CMD.EAS_SWITCH.",
5816
5827
  requires: [CAMERA_CMD.EAS_SWITCH],
5817
5828
  write: (v, ctx) => setScalar(CAMERA_CMD.EAS_SWITCH, asBool(v) ? 1 : 0, ctx, "auto")
@@ -5829,6 +5840,7 @@ var CAMERA_MEMBERS = {
5829
5840
  kind: "boolean",
5830
5841
  writeOnly: true,
5831
5842
  provenance: "verified",
5843
+ available: isCameraCodec,
5832
5844
  description: "Privacy mode (PRIVACY_MODE 6250) \u2014 the multi-frame burst the sink plays.",
5833
5845
  write: (v, ctx) => privacyCommand(asBool(v), ctx.channel)
5834
5846
  },
@@ -5842,6 +5854,7 @@ var CAMERA_MEMBERS = {
5842
5854
  type: "bool",
5843
5855
  kind: "boolean",
5844
5856
  provenance: "verified",
5857
+ available: isCameraCodec,
5845
5858
  readAvailable: (ctx) => !hasCapability(ctx, "doorbell"),
5846
5859
  readAliases: [{ paramType: CAMERA_CMD.DOORBELL_LED, available: (ctx) => hasCapability(ctx, "doorbell") }],
5847
5860
  requiresRead: true,
@@ -5865,28 +5878,28 @@ var CAMERA_MEMBERS = {
5865
5878
  * The refusal REJECTS on the four that answer with a promise, and THROWS on
5866
5879
  * {@link CAMERA_MEMBERS.recordFragments}, which answers with a handle.
5867
5880
  */
5868
- snapshotStored: provided("media", (m) => m.snapshotStored && (() => m.snapshotStored()), "Latest validated push thumbnail retained in memory.", ["snapshot"]),
5869
- snapshotLive: provided("media", (m, { ctx, read }) => async (opts) => {
5881
+ snapshotStored: provided("media", (m, { ctx }) => isCameraCodec(ctx) && m.snapshotStored && (() => m.snapshotStored()), "Latest validated push thumbnail retained in memory.", ["snapshot"]),
5882
+ snapshotLive: provided("media", (m, { ctx, read }) => isCameraCodec(ctx) && (async (opts) => {
5870
5883
  refuseWhenDisabled(ctx, read);
5871
5884
  return m.snapshotLive({ powered: poweredOf(ctx), ...opts });
5872
- }, "Fresh still decoded from a short live burst."),
5885
+ }), "Fresh still decoded from a short live burst."),
5873
5886
  live: provided("media", (m, { ctx, read }) => async (opts) => {
5874
5887
  refuseWhenDisabled(ctx, read);
5875
5888
  return m.live({ powered: poweredOf(ctx), ...opts });
5876
5889
  }, "Open a managed live stream."),
5877
- record: provided("media", (m, { ctx, read }) => async (...args) => {
5890
+ record: provided("media", (m, { ctx, read }) => isCameraCodec(ctx) && (async (...args) => {
5878
5891
  refuseWhenDisabled(ctx, read);
5879
5892
  return m.record(...args);
5880
- }, "Record N seconds \u2192 an mp4/h264 buffer."),
5881
- openReadable: provided("media", (m, { ctx, read }) => m.openReadable && (async (opts) => {
5893
+ }), "Record N seconds \u2192 an mp4/h264 buffer."),
5894
+ openReadable: provided("media", (m, { ctx, read }) => isCameraCodec(ctx) && m.openReadable && (async (opts) => {
5882
5895
  refuseWhenDisabled(ctx, read);
5883
5896
  return m.openReadable({ powered: poweredOf(ctx), ...opts });
5884
5897
  }), "Open a node:stream Readable of the live feed."),
5885
- recordFragments: provided("media", (m, { ctx, read }) => m.recordFragments && ((opts) => {
5898
+ recordFragments: provided("media", (m, { ctx, read }) => isCameraCodec(ctx) && m.recordFragments && ((opts) => {
5886
5899
  refuseWhenDisabled(ctx, read);
5887
5900
  return m.recordFragments({ powered: poweredOf(ctx), ...opts });
5888
5901
  }), "Continuous fragmented-MP4 (CMAF) recording."),
5889
- downloadRecording: provided("media", (m) => m.downloadRecording && ((opts) => m.downloadRecording(opts)), "Download a recording the station holds \u2192 H.264 and AAC elementary streams."),
5902
+ downloadRecording: provided("media", (m, { ctx }) => isCameraCodec(ctx) && m.downloadRecording && ((opts) => m.downloadRecording(opts)), "Download a recording the station holds \u2192 H.264 and AAC elementary streams."),
5890
5903
  /**
5891
5904
  * Push audio from the host to this camera's speaker. Gated on the **speaker** param specifically —
5892
5905
  * not the `audio` capability, which resolves on a microphone alone and would advertise a speaker the
@@ -5894,7 +5907,7 @@ var CAMERA_MEMBERS = {
5894
5907
  * power hint `live` does; without it a battery camera talked to with no stream running would stream
5895
5908
  * unbounded.
5896
5909
  */
5897
- talkback: provided("media", (m, { ctx }) => m.talkback && ctx.paramIds.has(AUDIO_CMD.AUDIO_SPEAKER) && ((opts) => m.talkback({ powered: poweredOf(ctx), ...opts })), "Push audio from the host to the camera's speaker.")
5910
+ talkback: provided("media", (m, { ctx }) => isCameraCodec(ctx) && m.talkback && ctx.paramIds.has(AUDIO_CMD.AUDIO_SPEAKER) && ((opts) => m.talkback({ powered: poweredOf(ctx), ...opts })), "Push audio from the host to the camera's speaker.")
5898
5911
  };
5899
5912
  var CAMERA = {
5900
5913
  capability: "camera",
@@ -5905,6 +5918,8 @@ var CAMERA = {
5905
5918
  detection: { codecs: ["camera"] },
5906
5919
  /** Only the no-argument power verbs, which carry no value for a member to hold. */
5907
5920
  actions({ ctx, sink }) {
5921
+ if (!isCameraCodec(ctx))
5922
+ return {};
5908
5923
  return {
5909
5924
  on: () => sink.dispatch(powerCommand(true, ctx)),
5910
5925
  off: () => sink.dispatch(powerCommand(false, ctx))
@@ -11603,6 +11618,8 @@ var MODEL_REGISTRY = {
11603
11618
  T8442: { codec: "camera", caps: ["arming"], name: "Indoor/Outdoor Cam 1080p" },
11604
11619
  // Hardwired wall-light camera; mains power asserted in MAINS_CAMERA_MODELS.
11605
11620
  T84A1: { codec: "camera", name: "Wall Light Cam S100" },
11621
+ // Video lock: device_type says lock, it also streams (live view verified, HomeBase 3-attached).
11622
+ T8530: { codec: "lock", caps: ["camera"], name: "Video Smart Lock S330" },
11606
11623
  // Sensors — the concrete sensor kind is curated (DeviceType 2 alone is ambiguous).
11607
11624
  T8900: { codec: "sensor", caps: ["contact"], name: "Entry Sensor" },
11608
11625
  T8910: { codec: "sensor", caps: ["battery"], name: "Motion Sensor" },