Grandstream GDS37xx Door System
The gds3710 driver controls Grandstream GDS3710 / GDS3705 IP video door systems via their HTTP API. It opens doors, fetches snapshots, syncs PIN/RFID credentials with GEM users, and emits PIN, RFID, doorbell, and door-open events into Access Control.
What the driver does
- Door open/close via the device's
/goform/apicmd challenge/response — uses the Remote PIN (P10457) the driver provisions on first connect.
- Snapshots via Basic-auth GET on
/snapshot/view.jpeg, with a fallback to the documented MJPEG challenge/response when Basic is rejected.
- Local user sync — GEM users covered by an Access Control rule referencing this device are pushed to the GDS local user list with their PIN and RFID. Users not in any rule are not pushed. The reverse direction (
sync_to_gem) imports GDS-native users back into GEM.
- Schedule + group mirroring — each access-control rule's
day_enable_mask / hour_enable_mask is translated into a device schedule slot (P15200..P15209), bound to a device group, and the group is assigned to the user. Access decisions then survive on the device alone, even with GEM offline.
- Event capture — door-open, doorbell, and keypad-resolved events are read from the device's event log every 5 s. A separate event-notification webhook captures system warnings (forced/held-open/tamper). Door/PIN/RFID events come from the eventlog poll, not the webhook.
Prerequisites
- A GDS3710 or GDS3705 reachable from the GEM controller on TCP/443 (HTTPS) — self-signed certs are accepted.
- The GDS admin password.
- The GEM controller and GDS should be on the same LAN. The driver auto-detects GEM's LAN IP for the webhook URL by asking the kernel which interface routes to the GDS.
No manual device-side setup is required. On first connect the driver:
- Enables HTTP API door-open (P15424=1) and provisions a Remote PIN (P10457) — generated as a random 8-digit value if not pre-set.
- Enables private-PIN mode (P10464=0) so per-user PINs work, and disables keypad SIP-dial fall-through (P15433=1) so PINs aren't silently routed to a SIP dial path.
- Returns PIN values in cleartext on local API responses (P15514=1) so
sync_to_gem can read them.
- Registers an Event Notification target pointing at GEM's auto-detected URL.
Setup
- System → Devices: add a device with driver
gds3710. Fill in:
ip — GDS LAN IP
password — admin password (secure)
- Add zones — one per door relay you want to control. Set
zone.address = 1 for door 1 or 2 for door 2 (GDS3710 only). Use subsystem gate, lock, or intercom as appropriate.
- Reference the device in Access Control rules. Set
access_device_id to the GDS device. On rule save the driver's access_rule_loaded listener fires sync_users automatically — every user covered by a rule on this device gets their PIN and RFID pushed.
Attributes
Required
| Attribute | Type | Notes |
|---|
ip | string | GDS LAN IP. |
password | string (secure) | Admin password. |
Optional
| Attribute | Type | Notes |
|---|
username | string | Defaults to admin. |
port | int | Defaults to 443. |
protocol | string | https (default) or http. |
remote_pin | string (secure) | Remote PIN for door open. Auto-generated 8-digit value on first connect if blank. |
webhook_base_url | string | Override the auto-detected URL Brivo events POST to (e.g., for reverse-proxy or NAT scenarios). |
webhook_token | string (secure, readonly) | Per-device random token embedded in the webhook URL. Generated on first connect. |
Runtime-populated read-only attributes include serial_number, firmware_version, door_state, last_door_open_at, last_keypad, last_doorbell_at, last_doorbell_target, last_warning, last_warning_at.
Commands
| Command | Args | Purpose |
|---|
open_door / open | address | Open the relay for door 1 or 2. Requires remote_pin and HTTP API door-open enabled (auto-handled on first connect). |
close_door / close | address | Close the relay (no-op for pulse-only relays). |
snapshot / get_image | — | Return a base64 JPEG snapshot. Used by the access-log capture chain. |
get_system_info | — | Refresh device firmware, serial, uptime, temperature, tamper-state attributes. |
get_network_info | — | Refresh MAC, IP, gateway, DNS attributes. |
get_users | — | List local users on the device. |
create_user | first_name, last_name, pin, rfid, room_num | Create a local user. PIN-only users get a synthetic ID 9000000 + auth_user_id. |
delete_user_by_id | device_user_id | Remove a user by device-side ID. |
sync_to_gem | — | Import GDS-native local users into GEM auth users (matched by name; new users created if no match). |
sync_users | — | Push every GEM user covered by a rule on this device to the GDS local list, mirroring rule schedules to device groups. |
register_webhook / unregister_webhook | — | Toggle the device's event-notification HTTP push to GEM. |
reboot_device | — | Reboot the GDS. |
dial | number | Dial a SIP number from the GDS. |
hangup | — | End the active call. |
disable_tamper / enable_tamper | — | Toggle the tamper alarm (P14350). Useful on bench / dev units where the enclosure is open. |
Events
The driver emits the following events into the rule engine and Attribute Triggers:
| Event | Source | Notes |
|---|
door_open | eventlog (code 301), webhook content match | last_door_open_at updated. |
keypad | eventlog (code 500) | Generic "keypad input was resolved." Fires for matched PINs and matched virtual numbers — the value field is opaque, so pin is not asserted from this code alone. |
pin_open | webhook content | Fires when the device's warning text indicates a PIN→door-open. Use this for "valid PIN" rules. |
doorbell | eventlog (code 504), webhook content | last_doorbell_at and last_doorbell_target updated. |
door_held_open, door_forced, tamper | webhook content | System warnings. |
warning | webhook | Always emitted alongside the specific event for any inbound webhook. |
Quirks
- The device default user-login timeout is 5 minutes; the driver re-authenticates at 4 minutes to keep the session warm. Concurrent logins are coalesced — the device only tracks one challenge per admin user, so simultaneous logins would invalidate each other.
- The eventlog response can leak the admin password in plaintext to authenticated callers. Treat the GDS session as sensitive.
- The local user list keys records by RFID card number (
ID). For PIN-only users with no card, the driver synthesizes an ID 9000000 + auth_user_id.
- Event notification (
register_webhook) only delivers system warnings — door/PIN/RFID/doorbell events come from the eventlog poll, which is the source of truth.
- After 5 failed admin logins (P14834) the device locks for 5 minutes. The driver honors
LoginLockTime and refuses to retry until the lockout expires, so it doesn't extend the lockout further.
Troubleshooting
| Symptom | Check |
|---|
Login keeps failing with ResCode 2 | Wrong password, or admin account is locked. The driver respects the device-side LoginLockTime; wait it out. |
open_door returns "Remote PIN is null" | The driver provisions P10457 on first connect — if it failed (e.g., session error during ensureRemotePin), restart the device or call ensureRemotePin after fixing the underlying issue. |
open_door returns "HTTP API open door function is disable" | P15424 is not set. The driver sets P15424=1 on first connect; if it didn't take, set it manually under System Settings → Access Settings → Enable HTTP API Remote Open Door. |
| Webhook never fires | The device must be able to reach the GEM controller's LAN IP and listen port. Check Maintenance → Event Notification in the GDS GUI; the driver populates URL/template when the webhook is registered. Set webhook_base_url if the auto-detected URL is not reachable from the GDS. |
| PIN entries don't unlock the door | Verify P15433=1 (keypad SIP-dial fall-through disabled) and P10464=0 (private PIN mode). Both are set automatically on first connect; the failure mode without them is silent — the device routes input to SIP dial first and never reaches the PIN check. |
- Access Control — rules, schedules, lockdown, duress
- Users — credential lifecycle, PIN, RFID
- Access Log — event audit, snapshots, facial recognition match scores