Использование сервисов OnVif PullPoint с Zeep

Мне трудно подписаться на услуги точки доступа OnVif в стандартных IP-камерах.

Клиент SOAP, который я использую, — это Zeep https://python-zeep.readthedocs.io/en/master/index.html

Кажется, что Zeep создает ошибочные данные xml, но я могу ошибаться (благодаря моим ограниченным знаниям SOAP). Давайте посмотрим на пример:

from zeep.client import Client, CachingClient, Settings
from zeep.wsse.username import UsernameToken
import zeep.helpers

import logging.config

# # Put Zeep into verbose mode
logging.config.dictConfig({
    'version': 1,
    'formatters': {
        'verbose': {
            'format': '%(name)s: %(message)s'
        }
    },
    'handlers': {
        'console': {
            'level': 'DEBUG',
            'class': 'logging.StreamHandler',
            'formatter': 'verbose',
        },
    },
    'loggers': {
        'zeep.transports': {
            'level': 'DEBUG',
            'propagate': True,
            'handlers': ['console'],
        },
    }
})

ip="192.168.0.134"; user="admin"; passwd="123456"; port=80 # My home cam 1.  Now you know its username and password.  :)

settings = Settings()
settings.strict = False
settings.xml_huge_tree = True

# # WSDL File
url = "https://www.onvif.org/ver10/events/wsdl/event.wsdl"

# # *** Events Service ***
xaddr = "http://"+ip+"/onvif/events_service"
print("creating a soap client with url = ", url)
zeep_client_events = CachingClient(wsdl=url, wsse=UsernameToken(user, passwd, use_digest=True), settings=settings)
print("soap client created")
print("binding to service")
ws_client_events = zeep_client_events.create_service("{http://www.onvif.org/ver10/events/wsdl}EventBinding", xaddr)
print("service OK")

# # *** PullPoint Service ***
xaddr = "http://"+ip+"/onvif/events_service"
print("creating a soap client with url = ", url)
zeep_client_pp = CachingClient(wsdl=url, wsse=UsernameToken(user, passwd, use_digest=True), settings=settings)
print("soap client created")
print("binding to service")
ws_client_pp = zeep_client_pp.create_service("{http://www.onvif.org/ver10/events/wsdl}PullPointSubscriptionBinding", xaddr)
print("service bound")

res = ws_client_events.CreatePullPointSubscription()

# # could see the namespaces like this:
# zeep_client_pp.namespaces

# # could create PullMessages' parameters like this:
# pm = zeep_client_pp.get_element("ns7:PullMessages")()

# So, this call never works
ws_client_pp.PullMessages(MessageLimit=1, Timeout="PT1S")

В зависимости от камеры это всегда приводит к «удаленному концу закрытого соединения без ответа» или, в противном случае, сервер отправляет сообщение о том, что значение недопустимо.

При переводе Zeep в подробный режим и проверке тела сообщения SOAP (это также подтверждено с помощью Wireshark) это выглядит так:

<soap-env:Body>
    <ns0:PullMessages xmlns:ns0="http://www.onvif.org/ver10/events/wsdl">
        <ns0:Timeout>P%P</ns0:Timeout>
        <ns0:MessageLimit>1</ns0:MessageLimit>
    </ns0:PullMessages>
</soap-env:Body>

Таким образом, кажется, что строка «PT1S» не попадает в тело сообщения, но вместо этого сохраняется «P%P»!

Как убедить Zeep вставить правильное время на место?

P. S. И, пожалуйста, не говорите мне использовать "python-onvif-zeep". Конечно, сначала я сделал это, а затем задал этот вопрос (примеры «python-onvif-zeep» для служб pullpoint не работают)


person El Sampsa    schedule 31.12.2018    source источник


Ответы (2)


Должен относиться к классу isodate.Duration. Это устраняет проблему:

import isodate
Timeout = isodate.Duration(seconds=10)
person El Sampsa    schedule 26.03.2019

Обратите внимание, что datetime, используемый в events.wsdl, похоже, имеет тип XML. В Python это поддерживается timedelta из datetime.

import datetime
timeout = datetime.timedelta(seconds=100)

ws_client_pp.PullMessages(MessageLimit=1, Timeout=timeout)

Выше применительно к zeep генерирует корректный запрос. На 100 с это ПТ1М40С.

Я все равно не могу прогрессировать с моей камерой, но продолжительность теперь установлена ​​​​правильно.

person Ryszard Styczynski    schedule 18.06.2019