You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

能否用Python脚本通过SOAP API批量配置Axis摄像机并创建ONVIF用户?

Axis摄像机批量配置ONVIF及迁移Avigilon解决方案

问题背景

有200台Axis品牌摄像机需迁移至Avigilon系统,所有摄像机均未配置ONVIF配置文件,还需启用麦克风功能。尝试通过Python脚本批量应用配置模板替代手动操作,但目前仅基础登录功能正常,SOAP命令要么格式错误要么请求超时;用VAPIX接口创建ONVIF用户时,请求返回200但实际未创建成功,不确定是否可通过VAPIX或WebUI创建ONVIF用户。

当前代码及问题

现有代码

import requests
from requests.auth import HTTPDigestAuth

# Axis camera WebUI credentials
username = 'root'    # Replace with your WebUI username
password = 'tent'    # Replace with your WebUI password

# Axis camera IP address and VAPIX endpoint for adding a user
camera_ip = '10.5.66.10'
url = f'http://{camera_ip}/axis-cgi/pwdgrp.cgi?action=add'

# Data for the new user (ensure valid username and password)
new_user_data = {
    'user': 'onvifuser',       # Ensure a valid username
    'pwd': 'onvifpassword',    # Password for the ONVIF account
    'grp': 'admin'             # Assign the group to 'admin'
}

# Send the request
try:
    response = requests.post(url, auth=HTTPDigestAuth(username, password), data=new_user_data)

    # Check if the request was successful
    if response.status_code == 200:
        print("ONVIF user created successfully.")
    else:
        print(f"Failed to create user. Status code: {response.status_code}")
        print(f"Response content: {response.text}")

except requests.exceptions.RequestException as e:
    print(f"An error occurred: {e}")

运行输出

ONVIF user created successfully.

核心问题

pwdgrp.cgi接口创建的是Axis WebUI用户,并非ONVIF专用用户,WebUI用户默认无ONVIF访问权限,因此即使请求返回成功,也无法用于ONVIF连接。

解决方案建议

1. 用VAPIX的param.cgi配置ONVIF用户及服务

Axis摄像机的大部分系统配置可通过param.cgi接口完成,包括启用ONVIF服务、创建ONVIF用户、启用麦克风等。以下是修改后的批量配置脚本示例:

import requests
from requests.auth import HTTPDigestAuth

# 全局配置
WEBUI_USER = 'root'
WEBUI_PWD = 'tent'
ONVIF_USER = 'onvifuser'
ONVIF_PWD = 'onvifpassword'
CAMERA_IPS = ['10.5.66.10']  # 可扩展为批量IP列表

def configure_camera(camera_ip):
    print(f"\n=== 配置摄像机 {camera_ip} ===")
    
    # 1. 启用ONVIF服务
    enable_onvif_data = {
        'action': 'update',
        'root.Network.ONVIF.Enabled': 'yes'
    }
    try:
        resp = requests.post(
            f'http://{camera_ip}/axis-cgi/param.cgi',
            auth=HTTPDigestAuth(WEBUI_USER, WEBUI_PWD),
            data=enable_onvif_data,
            timeout=15
        )
        if resp.status_code == 200:
            print("✅ ONVIF服务已启用")
        else:
            print(f"❌ 启用ONVIF服务失败,状态码: {resp.status_code}")
            print(f"响应内容: {resp.text}")
    except Exception as e:
        print(f"❌ 启用ONVIF服务出错: {str(e)}")
    
    # 2. 创建ONVIF用户(使用索引1,若已有用户需调整索引)
    add_onvif_user_data = {
        'action': 'update',
        'root.Network.ONVIF.User.1.Username': ONVIF_USER,
        'root.Network.ONVIF.User.1.Password': ONVIF_PWD,
        'root.Network.ONVIF.User.1.Enabled': 'yes',
        'root.Network.ONVIF.User.1.Permission': 'admin'
    }
    try:
        resp = requests.post(
            f'http://{camera_ip}/axis-cgi/param.cgi',
            auth=HTTPDigestAuth(WEBUI_USER, WEBUI_PWD),
            data=add_onvif_user_data,
            timeout=15
        )
        if resp.status_code == 200:
            # 验证用户是否创建成功
            check_resp = requests.get(
                f'http://{camera_ip}/axis-cgi/param.cgi?action=list&group=root.Network.ONVIF.User',
                auth=HTTPDigestAuth(WEBUI_USER, WEBUI_PWD),
                timeout=10
            )
            if ONVIF_USER in check_resp.text:
                print("✅ ONVIF用户创建成功")
            else:
                print("❌ ONVIF用户未创建成功,请检查参数或用户索引")
        else:
            print(f"❌ 创建ONVIF用户失败,状态码: {resp.status_code}")
            print(f"响应内容: {resp.text}")
    except Exception as e:
        print(f"❌ 创建ONVIF用户出错: {str(e)}")
    
    # 3. 启用麦克风
    enable_mic_data = {
        'action': 'update',
        'root.Audio.Input.1.Enabled': 'yes'
    }
    try:
        resp = requests.post(
            f'http://{camera_ip}/axis-cgi/param.cgi',
            auth=HTTPDigestAuth(WEBUI_USER, WEBUI_PWD),
            data=enable_mic_data,
            timeout=15
        )
        if resp.status_code == 200:
            print("✅ 麦克风已启用")
        else:
            print(f"❌ 启用麦克风失败,状态码: {resp.status_code}")
            print(f"响应内容: {resp.text}")
    except Exception as e:
        print(f"❌ 启用麦克风出错: {str(e)}")

# 批量处理所有摄像机
for ip in CAMERA_IPS:
    configure_camera(ip)

2. 关键注意事项

  • 参数适配:不同型号的Axis摄像机参数路径可能略有差异,可通过http://<camera_ip>/axis-cgi/param.cgi?action=list&group=root.Network.ONVIF或root.Audio查看具体参数名
  • 用户索引:若摄像机已有ONVIF用户,需调整root.Network.ONVIF.User.X中的X为下一个可用索引(比如从1开始,依次递增)
  • 超时设置:添加timeout参数避免因网络延迟导致请求超时
  • 权限验证:确保使用的WebUI用户拥有管理员权限,能够修改系统配置

3. SOAP命令修复思路

若坚持使用ONVIF SOAP API,需确保:

  • 正确构造符合ONVIF规范的SOAP信封(需包含命名空间和正确的操作节点)
  • 请求地址为摄像机的ONVIF服务端点,通常为http://<camera_ip>/onvif/device_service
  • 请求头设置Content-Type: application/soap+xml; charset=utf-8
  • 使用Digest认证方式

示例SOAP请求(创建ONVIF用户):

<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope"
               xmlns:tds="http://www.onvif.org/ver10/device/wsdl">
  <soap:Body>
    <tds:CreateUsers>
      <tds:Users>
        <tds:User>
          <tds:Username>onvifuser</tds:Username>
          <tds:Password>onvifpassword</tds:Password>
          <tds:UserLevel>Administrator</tds:UserLevel>
        </tds:User>
      </tds:Users>
    </tds:CreateUsers>
  </soap:Body>
</soap:Envelope>

内容的提问来源于stack exchange,提问作者Dakota House

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.18 19:35:02