Browse Source

Merge pull request #7 from OpenIPC/dvrip-detect-motion-config

dvrip: add Detect (motion detection) config wrappers
master
Dmitry Ilyin 5 days ago
committed by GitHub
parent
commit
fb0d351c06
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 2
      AlarmServer.py
  2. 37
      README.md
  3. 8
      asyncio_dvrip.py
  4. 7
      connect.py
  5. 8
      dvrip.py

2
AlarmServer.py

@ -40,7 +40,7 @@ while True:
sleep(0.1) # Just for recive whole packet
data = conn.recv(len_data)
conn.close()
reply = json.loads(data, encoding="utf8")
reply = json.loads(data.decode("utf-8", errors="replace").rstrip("\x00\n"))
print(datetime.now().strftime("[%Y-%m-%d %H:%M:%S]>>>"))
print(head, version, session, sequence_number, msgid, len_data)
print(json.dumps(reply, indent=4, sort_keys=True))

37
README.md

@ -460,6 +460,43 @@ cloudEnabled = False
cam.set_info("NetWork.Nat", { "NatEnable" : cloudEnabled })
```
## Motion detection
Xiongmai cameras typically do **not** expose ONVIF `AnalyticsService`, so
motion detection cannot be configured through ONVIF. On some firmwares it
is also off by default. Configure it directly over the native protocol via
the `Detect` config path:
```python
# Inspect current config (per-channel arrays)
print(cam.get_detect_info())
# {'HumanDetection': [{'Enable': False, ...}],
# 'MotionDetect': [{'Enable': True,
# 'EventHandler': {'RecordEnable': True,
# 'AlarmOutEnable': False, ...},
# 'Level': 5}]}
# Enable motion detection at sensitivity 5 with event-triggered recording.
# Sparse payloads are merged — fields you omit keep their current values.
cam.set_detect_info({
"MotionDetect": [{"Enable": True,
"EventHandler": {"RecordEnable": True},
"Level": 5}],
"HumanDetection": [{"Enable": False}],
})
```
The equivalent low-level call is `cam.set_info("Detect", ...)` — both
shapes work; the wrapper just documents the path.
Receiving the events is a separate problem. Some XM firmwares push
`AlarmInfo` packets over the existing TCP session, so registering
`setAlarm()` + `alarmStart()` is enough; on others the camera only emits
to a separately-configured alarm server (see `AlarmServer.py` and the
`EventHandler.AlarmInfo` / `MsgtoNetEnable` fields). If `setAlarm()`
silently produces no callbacks even while recordings show motion is
detected, the camera is likely in the latter group.
## Add user and change password
```python

8
asyncio_dvrip.py

@ -580,6 +580,14 @@ class DVRIPCam(object):
code = 1042
return await self.get_command("Simplify.Encode", code)
async def get_detect_info(self):
"""Read 'Detect' config: per-channel MotionDetect / HumanDetection / etc."""
return await self.get_info("Detect")
async def set_detect_info(self, data):
"""Update 'Detect' config. Sparse payloads are merged with current state."""
return await self.set_info("Detect", data)
async def recv_json(self, buf=bytearray()):
p = compile(b".*({.*})")

7
connect.py

@ -27,6 +27,13 @@ info["OSDInfo"][0]["OSDInfoWidget"]["PreviewBlend"] = True
# info["OSDInfo"][0]["OSDInfoWidget"]["RelativePos"] = [6144,6144,8192,8192]
cam.set_info("fVideo.OSDInfo", info)
# enc_info = cam.get_info("Simplify.Encode")
# Motion detection: turn it on and route events into recording.
# cam.set_detect_info({
# "MotionDetect": [{"Enable": True,
# "EventHandler": {"RecordEnable": True},
# "Level": 5}],
# "HumanDetection": [{"Enable": False}],
# })
# Alarm example
def alarm(content, ids):
print(content)

8
dvrip.py

@ -703,6 +703,14 @@ class DVRIPCam(object):
code = 1042
return self.get_command("Simplify.Encode", code)
def get_detect_info(self):
"""Read 'Detect' config: per-channel MotionDetect / HumanDetection / etc."""
return self.get_info("Detect")
def set_detect_info(self, data):
"""Update 'Detect' config. Sparse payloads are merged with current state."""
return self.set_info("Detect", data)
def recv_json(self, buf=bytearray()):
p = compile(b".*({.*})")

Loading…
Cancel
Save