The module keeps one persistent HTTP connection to an Imou DB61i doorbell (CGI eventManager.cgi, Digest authentication),
stores every event in a log, calls your handler and serves photos and videos from the SD card through the MajorDoMo control panel.
The Imou cloud is not needed: the local network and the device password are enough.
admin. The password is the device password, the same one used for CGI and RTSP (see below).Device password is used for local CGI and RTSP access (login admin). It is set and changed in Imou Life:
doorbell settings → device name → "Device password"; on some devices in the Dahua DMSS app.
If the curl command from the "Checking" section below and video download work with a password, that is the one.
The Security Code is a different value and the module does not need it. It is the device verification code: Imou Life → doorbell → "⋮" menu →
"About device" → device picture → the screen with the device's own QR code. On firmware 1.000.0000003.1.R it was
the ONVIF password and may differ from the device password.
Wrong password. The doorbell locks the account after a few failed attempts, so after HTTP 401 the module waits 5, then 15, then 30 minutes. Saving the settings retries immediately.
The handler runs for every new event right after it is logged, unknown codes included.
It runs in a separate request to /api.php (like MQTT handlers), so slow or failing code never blocks event reception.
Each call's status is shown in the log; errors are shown in the event card and on the Diagnostics tab.
$params, as in any MajorDoMo method.$params and as $event.$params = array(
'id' => 418, // log record ID
'code' => 'AlarmLocal', // Code from the camera message
'action' => 'Start',
'index' => 0, // int or null
'received_at' => '2026-11-05T23:21:02.264+03:00',
'device_time' => null, // device time if present in data
'fields' => array('Code' => 'AlarmLocal', 'action' => 'Start', 'index' => '0'),
'data' => null, // decoded data (array) or null
'data_error' => null, // error text if data is not valid JSON
'raw' => 'Code=AlarmLocal;action=Start;index=0',
'media' => array(), // files known at call time
);
For NewFile with a valid path, media holds an entry like
array('id' => 7, 'event_id' => 419, 'type' => 'jpg', 'size' => 32879, 'path' => '/mnt/sd/…', 'start' => …, 'end' => …,
'preview_url' => '/admin.php?…', 'download_url' => '/admin.php?…').
When a video is confidently matched to a call (the recording interval in its file name contains exactly one button press),
'call' => array('event_id' => 418, 'match' => 'interval') is added.
The links open only in a browser with control panel access. The device password is never part of the array.
A button press is AlarmLocal / Start / index=0, the release about 10 seconds later is AlarmLocal / Stop.
NewFile also comes with motion, so it is not a call trigger. The first JPEG usually appears ~1 second after the press,
the MP4 about a minute later, when the recording ends. The AlarmLocal Start handler is not called again when files appear.
PHP code example (the Doorbell object is just an example):
if ($event['code'] === 'AlarmLocal' && $event['index'] === 0) {
if ($event['action'] === 'Start') {
setGlobal('Doorbell.call', 1);
} elseif ($event['action'] === 'Stop') {
setGlobal('Doorbell.call', 0);
}
}
Sending the first photo, for example to Telegram:
if ($event['code'] === 'NewFile' && !empty($event['media']) && $event['media'][0]['type'] === 'jpg') {
include_once(DIR_MODULES . 'imou_doorbell/imou_doorbell.class.php');
$doorbell = new imou_doorbell();
$file = ROOT . 'cms/cached/doorbell_' . $event['media'][0]['id'] . '.jpg';
if ($doorbell->fetchMediaToFile($event['media'][0]['id'], $file)) {
// ... send $file, then remove it: unlink($file);
}
}
Errors thrown as Exception inside MajorDoMo object methods are caught by the core and recorded in System errors;
other errors and warnings go to the module's Diagnostics tab.
If a property such as Doorbell.call is already updated by ONVIF, a cloud webhook or another module, unlink the old source manually,
otherwise one call will run the scenario twice.
The module stores metadata only. When viewed, a file is requested from the doorbell (RPC_Loadfile) and streamed to the browser,
it is never written to the MajorDoMo disk. Video supports seeking (Range). If the browser cannot play the codec, use "Download".
When the camera deletes or overwrites a file, the link shows a clear message. Links work only for control panel users.
The Live tab shows RTSP links without the password: main stream, sub stream and an alternative sub stream path needed by some firmwares. "Check RTSP" finds out from the server which paths answer. Enter login and password in the player itself (VLC etc.).
Browsers cannot play RTSP, so the tab shows the current camera picture (snapshot.cgi), requested by the module on the server
and streamed to the browser. Refresh it manually or every couple of seconds. For real-time video use an RTSP link in an external player.
The doorbell heartbeat (every 5 seconds) is not logged: it only refreshes "last activity". Service events you do not need
(for example RtspSessionState and RtspSessionDisconnect when an RTSP player connects) can be listed in
"Do not log codes": such events are neither logged nor passed to the handler.
Records older than the retention period (3 days by default) are removed hourly together with their media metadata and links. Files on the SD card are left to the camera. "Clean up now" on the Diagnostics tab runs the cleanup immediately.
VideoMotion / VideoMotionInfo and possibly NewFile.AlarmLocal Start appears and about 10 seconds later AlarmLocal Stop (highlighted rows).curl --digest --user admin --globoff --no-buffer --max-time 60 \ 'http://DOORBELL_IP/cgi-bin/eventManager.cgi?action=attach&codes=[All]&heartbeat=5'