Это документация основана только на моём опыте работы с hikvision ISAPI. В будущем я буду дополнять её.
Hikvision ISAPI (Internet Server API) - это интерфейс для работы с устройствами видеонаблюдения и контроля доступа.
- Python 3.10+
requests- для HTTP-запросовrequests.auth- для Digest Authpython-dotenv- для работы с .env файлами (необязательно)
pip install requestsЭта документация предназначена для разработчиков Python, которые хотят интегрировать устройства Hikvision с собственными приложениями.
Сначала приступим к Аутентификация, для этого нужно логин и пароль администратора
Можно протестировать подключение с помощью запроса к базовому эндпоинту устройства, например:
Файл: infodevice.py
http://IP/ISAPI/System/deviceInfo
Этот эндпоинт возвращает информацию о самом устройстве.
import requests
from requests.auth import HTTPDigestAuth
# Логин и пароль администратора
username = "admin"
password = "12345"
# URL устройства
url = "http://IP/ISAPI/System/deviceInfo"
# Аутентификация Digest
auth = HTTPDigestAuth(username, password)
# Выполняем GET-запрос
response = requests.get(url, auth=auth, verify=False)
# Проверяем результат
print("Статус:", response.status_code)
print("Ответ устройства:")
print(response.text)
<?xml version="1.0" encoding="UTF-8"?>
<DeviceInfo version="2.0" xmlns="http://www.isapi.org/ver20/XMLSchema">
<deviceName>in</deviceName>
<deviceID></deviceID>
<model></model>
<serialNumber></serialNumber>
<macAddress></macAddress>
<firmwareVersion></firmwareVersion>
<firmwareReleasedDate></firmwareReleasedDate>
<encoderVersion></encoderVersion>
<encoderReleasedDate></encoderReleasedDate>
<deviceType></deviceType>
<subDeviceType>accessControlTerminal</subDeviceType>
<telecontrolID></telecontrolID>
<localZoneNum></localZoneNum>
<alarmOutNum></alarmOutNum>
<electroLockNum></electroLockNum>
<RS485Num></RS485Num>
<manufacturer>hikvision</manufacturer>
<OEMCode></OEMCode>
<bspVersion></bspVersion>
<dspVersion></dspVersion>
<marketType></marketType>
<productionDate></productionDate>
</DeviceInfo>
После успешной аутентификации можно получать события прихода и ухода сотрудников через ISAPI. Обычно используется эндпоинт:
Файл: accesscontrol.py
http://IP/ISAPI/AccessControl/AcsEvent?format=json
Пример запроса на Python
import requests
from requests.auth import HTTPDigestAuth
username = "admin"
password = "123456"
auth = HTTPDigestAuth(username, password)
url = "http://IP/ISAPI/AccessControl/AcsEvent?format=json"
start_time_str = "2025-01-01T00:00:00Z"
end_time_str = "2025-01-1T23:59:59Z"
data = {
"AcsEventCond": {
"searchID": "1",
"searchResultPosition": 0,
"maxResults": 30, # Максимум событий за один запрос
"major": 5, # Только взоды
"minor": 75, # Вход по лицу
"startTime": start_time_str,
"endTime": end_time_str
}
}
response = requests.post(url, auth=auth, json=data, timeout=30)
print(response.status_code)
print(response.text)
{
"AcsEvent": {
"searchID": "1",
"totalMatches": 36,
"responseStatusStrg":"MORE",
"numOfMatches": 1,
"InfoList":[{
"major": 5,
"minor": 75,
"time": "2025-11-15T21:03:07+05:00",
"cardNo": "18446744073609552366",
"cardType": 1,
"name": "Travis",
"cardReaderNo": 1,
"doorNo": 1,
"employeeNoString": "1030388848",
"serialNo": 111736,
"userType": "normal",
"currentVerifyMode": "faceOrFpOrCardOrPw",
"mask": "no",
"pictureURL": "",
"FaceRect": {
"height": 0.288,
"width": 0.513,
"x": 0.168,
"y": 0.349
}
}]
}
}
maxResults событий (в примере — 30).
Если за указанный период событий больше, вернутся только первые 30.
Чтобы получить все события за большой период, нужно использовать постраничный запрос, увеличивая searchResultPosition или как сделать как я разделить время на чанки по 2 часа или на 1 час.
Пример c решение данной проблемы находниться в allaccesscontrol.py
Для получения списка пользователей, зарегистрированных в терминале доступа Hikvision, используется ISAPI-метод:
http://IP/ISAPI/AccessControl/UserInfo/search?format=json
Файл: getusers.py
import requests
from requests.auth import HTTPDigestAuth
import json
username = "admin"
password = "123456"
auth = HTTPDigestAuth(username, password)
url = "http://IP/ISAPI/AccessControl/UserInfo/search?format=json"
data = {
"UserInfoSearchCond": {
"searchID": "1",
"searchResultPosition": 1,
"maxResults": 1, # только 30 ответов
"userType": "normal" # выводит всёх нормальных пользователь
}
}
response = requests.post(url=url, auth=auth, data=json.dumps(data))
print(response.status_code)
print(response.text)
{
"UserInfoSearch": {
"searchID": "1",
"responseStatusStrg": "MORE",
"numOfMatches": 1,
"totalMatches": 97,
"UserInfo":[{
"employeeNo":"1",
"name": "NAME",
"userType":"normal",
"sortByNamePosition":1,
"sortByNameFlag":"#",
"closeDelayEnabled":false,
"Valid":{
"enable":true,
"beginTime":"2025-05-12T10:11:45",
"endTime":"2035-05-12T23:59:59",
"timeType":"local"
},
"belongGroup":"",
"password":"",
"doorRight":"1",
"RightPlan":[{
"doorNo": 1,
"planTemplateNo": "1"
}],
"maxOpenDoorTime":0,
"openDoorTime":0,
"roomNumber":99,
"floorNumber":99,
"localUIRight":false,
"gender":"unknown",
"numOfCard":1,
"numOfFP":0,
"numOfFace":1,
"PersonInfoExtends":[{
"value":""
}],
"faceURL": ""
}]
}
}
Если отправить GET запрос, можно получить более подробную информацию.
"searchResultPosition": N - нужно увеличивать для получение всех пользователей.
Файл с решением данной проблемы находниться allgetusers.py