Thin wrappers `get_detect_info()` / `set_detect_info(data)` in both the
sync (`dvrip.py`) and async (`asyncio_dvrip.py`) clients for the
top-level `Detect` config path — per-channel MotionDetect /
HumanDetection (and, on multi-channel NVRs, BlindDetect / LossDetect).
The library already supported this via the generic `get_info("Detect")` /
`set_info("Detect", …)`, but the path and payload shape were undocumented.
README now carries a worked example showing the per-channel-array schema
and the sparse-merge semantics (fields omitted from a SET payload retain
their current value), plus a caveat that AlarmInfo push behaviour is
firmware-dependent — some XM builds emit events to the existing TCP
session, others only to a separately-configured `AlarmServer`, and some
do neither.
Verified on a live XM IPC unit (single-channel, hostname
IVG85HG50PYA-S-2): the canonical OpenIPC "turn motion detection on"
snippet returns `Ret: 100`, round-trip GET shows the change, sparse merge
works (`{"MotionDetect":[{"Level":4}]}` flips only `Level`).
Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
Previously --backup required telnet to already be enabled, so a fresh
camera needed two invocations: one to enable telnet (with reboot), then
one to back up. Now --backup auto-enables telnet via the InstallDesc
exploit when port 23 is closed, waits for the reboot, and proceeds. The
script also exits 0 / non-0 so it composes cleanly in shell loops and
automation:
for ip in 10.0.0.10 10.0.0.11 10.0.0.12; do
python3 telnet_opener.py "$ip" -b --nfs 10.0.0.1:/srv/ipctool
done
The old `-b/--backup` mounted a now-defunct NFS share at 95.217.179.189
and ran `ipctool -w` (the silent S3-upload mode disabled per
OpenIPC/ipctool#78). Both pieces are gone. The new flow telnets in as
root/xmhdipc, mounts a user-supplied NFS share, and runs
`ipctool backup /utils/backup-<MAC>` so the dump stays on the user's
network.
Also fall back to the XMV4 SupportFlashType list when the camera's
SWVER is unknown — without this, older firmware (e.g. 50H20L /
00031520) rejects the InstallDesc payload entirely.