Skip to content

Support Motion/PIR Sensor E20 (T90M0) with live motion detected events#905

Open
Kosta-Github wants to merge 2 commits into
bropat:developfrom
Kosta-Github:fix/hb3-pir-sensor-e20-live-events
Open

Support Motion/PIR Sensor E20 (T90M0) with live motion detected events#905
Kosta-Github wants to merge 2 commits into
bropat:developfrom
Kosta-Github:fix/hb3-pir-sensor-e20-live-events

Conversation

@Kosta-Github

Copy link
Copy Markdown

Summary

Fixes #903.

The Motion/PIR Sensor E20 (device_type 127, PIR_SENSOR_E20) — e.g. paired to a HomeBase 3 — was deserialized to UnknownDevice and never emitted motion events.

  • isMotionSensor() / isSensor() now match PIR_SENSOR_E20 (new isPirSensorE20() guard), so EufySecurity.handleDevices() instantiates it as a MotionSensor instead of UnknownDevice. DeviceMotionDetected is declared in its property metadata.
  • The HomeBase 3 delivers live motion over P2P as a CMD_NOTIFY_PAYLOAD whose inner cmd is 1829, carrying a generic params batch ({"params":[{"param_type":1605,"param_value":"<unix-ms>"}]}). This was previously dropped as “Not implemented”; each param is now routed through the existing "parameter" pipeline so the owning device receives a live raw-property update.
  • MotionSensor maps a fresh CMD_MOTION_SENSOR_PIR_EVT (param 1605) timestamp advance to DeviceMotionDetected and emits a motion detected event with an auto-reset cooldown — this sensor reports motion as a last-detection timestamp rather than a CusPushEvent.MOTION_SENSOR_PIR push.

The result is a live motion detected event, without requiring a full cloud refresh.

Test plan

  • Verified on real hardware (Motion/PIR Sensor E20 / T90M0 paired to a HomeBase 3, eufy-security-client 3.8.0) over a local P2P connection:
    • The device is now instantiated as MotionSensor (no longer UnknownDevice).
    • Triggering the sensor produces a live CMD_NOTIFY_PAYLOAD (cmd 1829) on the device channel; the param batch (incl. 1605) is routed and a motion detected event is emitted within ~1s, with no cloud refresh.
  • npm run build:ts compiles cleanly (branch rebased onto develop).

Fixes bropat#903.

The Motion/PIR Sensor E20 (device_type 127, PIR_SENSOR_E20), e.g. paired to a
HomeBase 3, was deserialized to UnknownDevice and never emitted motion events.

Changes:
- isMotionSensor()/isSensor() now match PIR_SENSOR_E20 (new isPirSensorE20()
  guard), so EufySecurity.handleDevices() instantiates it as MotionSensor
  instead of UnknownDevice. DeviceMotionDetected is declared in its property
  metadata.
- The HomeBase 3 delivers live motion over P2P as a CMD_NOTIFY_PAYLOAD with
  inner cmd 1829 carrying a generic params batch
  ({"params":[{"param_type":1605,"param_value":"<ts>"}]}). This was previously
  dropped as "Not implemented"; each param is now routed through the existing
  "parameter" pipeline so the owning device gets a live raw-property update.
- MotionSensor maps a fresh CMD_MOTION_SENSOR_PIR_EVT (param 1605) timestamp
  advance to DeviceMotionDetected and emits a "motion detected" event with an
  auto-reset cooldown (the sensor reports motion as a last-detection timestamp
  rather than a CusPushEvent.MOTION_SENSOR_PIR push).

Motion is delivered live, without requiring a full cloud refresh.

Co-authored-by: Cursor <cursoragent@cursor.com>
@Kosta-Github Kosta-Github force-pushed the fix/hb3-pir-sensor-e20-live-events branch from 187eca6 to 628d591 Compare June 1, 2026 06:46
Comment thread src/p2p/session.ts Outdated
);
this.emit("hub notify update");
} else if (
json.cmd === 1829 &&

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we please define like this } else if (json.cmd === CommandType.CMD_STORAGE_INFO_HB3) {

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done in 6211d51 — thanks!

Small caveat: 1829 is already defined as CommandType.CMD_HUB_NOTIFY_UPDATE, and there's an unconditional else if (json.cmd === CommandType.CMD_HUB_NOTIFY_UPDATE) branch right above this one (it landed via the release/4.0.0 merge after I first branched). So simply renaming 1829 → the constant on a separate branch would have left this code unreachable (the earlier branch swallows every 1829 message).

To keep it reachable while still using the named constant, I folded the Sub-1G params-batch handling into that existing CMD_HUB_NOTIFY_UPDATE branch, guarded by the presence of a params array, and kept the plain "hub notify update" emit in the else.

Address review feedback: reference the named CommandType constant rather
than the literal 1829.

Since CMD_HUB_NOTIFY_UPDATE (1829) already had an unconditional branch
above, fold the Sub-1G params-batch handling into that branch (guarded by
the presence of a "params" array) so it stays reachable instead of being
shadowed as dead code.

Co-authored-by: Cursor <cursoragent@cursor.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants