onvif-python 0.1.2__tar.gz → 0.1.4__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (128) hide show
  1. {onvif_python-0.1.2/onvif_python.egg-info → onvif_python-0.1.4}/PKG-INFO +28 -10
  2. {onvif_python-0.1.2 → onvif_python-0.1.4}/README.md +27 -9
  3. {onvif_python-0.1.2 → onvif_python-0.1.4}/onvif/cli/interactive.py +231 -20
  4. {onvif_python-0.1.2 → onvif_python-0.1.4}/onvif/cli/main.py +94 -21
  5. onvif_python-0.1.4/onvif/cli/utils.py +1247 -0
  6. {onvif_python-0.1.2 → onvif_python-0.1.4}/onvif/operator.py +6 -0
  7. {onvif_python-0.1.2 → onvif_python-0.1.4/onvif_python.egg-info}/PKG-INFO +28 -10
  8. {onvif_python-0.1.2 → onvif_python-0.1.4}/pyproject.toml +1 -1
  9. onvif_python-0.1.2/onvif/cli/utils.py +0 -475
  10. {onvif_python-0.1.2 → onvif_python-0.1.4}/LICENSE.md +0 -0
  11. {onvif_python-0.1.2 → onvif_python-0.1.4}/MANIFEST.in +0 -0
  12. {onvif_python-0.1.2 → onvif_python-0.1.4}/onvif/__init__.py +0 -0
  13. {onvif_python-0.1.2 → onvif_python-0.1.4}/onvif/cli/__init__.py +0 -0
  14. {onvif_python-0.1.2 → onvif_python-0.1.4}/onvif/cli/__main__.py +0 -0
  15. {onvif_python-0.1.2 → onvif_python-0.1.4}/onvif/client.py +0 -0
  16. {onvif_python-0.1.2 → onvif_python-0.1.4}/onvif/services/__init__.py +0 -0
  17. {onvif_python-0.1.2 → onvif_python-0.1.4}/onvif/services/accesscontrol.py +0 -0
  18. {onvif_python-0.1.2 → onvif_python-0.1.4}/onvif/services/accessrules.py +0 -0
  19. {onvif_python-0.1.2 → onvif_python-0.1.4}/onvif/services/actionengine.py +0 -0
  20. {onvif_python-0.1.2 → onvif_python-0.1.4}/onvif/services/analytics/analytics.py +0 -0
  21. {onvif_python-0.1.2 → onvif_python-0.1.4}/onvif/services/analytics/ruleengine.py +0 -0
  22. {onvif_python-0.1.2 → onvif_python-0.1.4}/onvif/services/analyticsdevice.py +0 -0
  23. {onvif_python-0.1.2 → onvif_python-0.1.4}/onvif/services/appmgmt.py +0 -0
  24. {onvif_python-0.1.2 → onvif_python-0.1.4}/onvif/services/authenticationbehavior.py +0 -0
  25. {onvif_python-0.1.2 → onvif_python-0.1.4}/onvif/services/credential.py +0 -0
  26. {onvif_python-0.1.2 → onvif_python-0.1.4}/onvif/services/deviceio.py +0 -0
  27. {onvif_python-0.1.2 → onvif_python-0.1.4}/onvif/services/devicemgmt.py +0 -0
  28. {onvif_python-0.1.2 → onvif_python-0.1.4}/onvif/services/display.py +0 -0
  29. {onvif_python-0.1.2 → onvif_python-0.1.4}/onvif/services/doorcontrol.py +0 -0
  30. {onvif_python-0.1.2 → onvif_python-0.1.4}/onvif/services/events/events.py +0 -0
  31. {onvif_python-0.1.2 → onvif_python-0.1.4}/onvif/services/events/notification.py +0 -0
  32. {onvif_python-0.1.2 → onvif_python-0.1.4}/onvif/services/events/pullpoint.py +0 -0
  33. {onvif_python-0.1.2 → onvif_python-0.1.4}/onvif/services/events/subscription.py +0 -0
  34. {onvif_python-0.1.2 → onvif_python-0.1.4}/onvif/services/imaging.py +0 -0
  35. {onvif_python-0.1.2 → onvif_python-0.1.4}/onvif/services/media.py +0 -0
  36. {onvif_python-0.1.2 → onvif_python-0.1.4}/onvif/services/media2.py +0 -0
  37. {onvif_python-0.1.2 → onvif_python-0.1.4}/onvif/services/provisioning.py +0 -0
  38. {onvif_python-0.1.2 → onvif_python-0.1.4}/onvif/services/ptz.py +0 -0
  39. {onvif_python-0.1.2 → onvif_python-0.1.4}/onvif/services/receiver.py +0 -0
  40. {onvif_python-0.1.2 → onvif_python-0.1.4}/onvif/services/recording.py +0 -0
  41. {onvif_python-0.1.2 → onvif_python-0.1.4}/onvif/services/replay.py +0 -0
  42. {onvif_python-0.1.2 → onvif_python-0.1.4}/onvif/services/schedule.py +0 -0
  43. {onvif_python-0.1.2 → onvif_python-0.1.4}/onvif/services/search.py +0 -0
  44. {onvif_python-0.1.2 → onvif_python-0.1.4}/onvif/services/security/advancedsecurity.py +0 -0
  45. {onvif_python-0.1.2 → onvif_python-0.1.4}/onvif/services/security/authorizationserver.py +0 -0
  46. {onvif_python-0.1.2 → onvif_python-0.1.4}/onvif/services/security/dot1x.py +0 -0
  47. {onvif_python-0.1.2 → onvif_python-0.1.4}/onvif/services/security/jwt.py +0 -0
  48. {onvif_python-0.1.2 → onvif_python-0.1.4}/onvif/services/security/keystore.py +0 -0
  49. {onvif_python-0.1.2 → onvif_python-0.1.4}/onvif/services/security/mediasigning.py +0 -0
  50. {onvif_python-0.1.2 → onvif_python-0.1.4}/onvif/services/security/tlsserver.py +0 -0
  51. {onvif_python-0.1.2 → onvif_python-0.1.4}/onvif/services/thermal.py +0 -0
  52. {onvif_python-0.1.2 → onvif_python-0.1.4}/onvif/services/uplink.py +0 -0
  53. {onvif_python-0.1.2 → onvif_python-0.1.4}/onvif/utils/__init__.py +0 -0
  54. {onvif_python-0.1.2 → onvif_python-0.1.4}/onvif/utils/error_handlers.py +0 -0
  55. {onvif_python-0.1.2 → onvif_python-0.1.4}/onvif/utils/exceptions.py +0 -0
  56. {onvif_python-0.1.2 → onvif_python-0.1.4}/onvif/utils/wsdl.py +0 -0
  57. {onvif_python-0.1.2 → onvif_python-0.1.4}/onvif/utils/xml_capture.py +0 -0
  58. {onvif_python-0.1.2 → onvif_python-0.1.4}/onvif/utils/zeep.py +0 -0
  59. {onvif_python-0.1.2 → onvif_python-0.1.4}/onvif/wsdl/ver10/accesscontrol/wsdl/index.html +0 -0
  60. {onvif_python-0.1.2 → onvif_python-0.1.4}/onvif/wsdl/ver10/accessrules/wsdl/accessrules.wsdl +0 -0
  61. {onvif_python-0.1.2 → onvif_python-0.1.4}/onvif/wsdl/ver10/accessrules/wsdl/index.html +0 -0
  62. {onvif_python-0.1.2 → onvif_python-0.1.4}/onvif/wsdl/ver10/actionengine.wsdl +0 -0
  63. {onvif_python-0.1.2 → onvif_python-0.1.4}/onvif/wsdl/ver10/advancedsecurity/wsdl/advancedsecurity.wsdl +0 -0
  64. {onvif_python-0.1.2 → onvif_python-0.1.4}/onvif/wsdl/ver10/advancedsecurity/wsdl/index.html +0 -0
  65. {onvif_python-0.1.2 → onvif_python-0.1.4}/onvif/wsdl/ver10/analyticsdevice.wsdl +0 -0
  66. {onvif_python-0.1.2 → onvif_python-0.1.4}/onvif/wsdl/ver10/appmgmt/wsdl/appmgmt.wsdl +0 -0
  67. {onvif_python-0.1.2 → onvif_python-0.1.4}/onvif/wsdl/ver10/appmgmt/wsdl/index.html +0 -0
  68. {onvif_python-0.1.2 → onvif_python-0.1.4}/onvif/wsdl/ver10/authenticationbehavior/wsdl/authenticationbehavior.wsdl +0 -0
  69. {onvif_python-0.1.2 → onvif_python-0.1.4}/onvif/wsdl/ver10/authenticationbehavior/wsdl/index.html +0 -0
  70. {onvif_python-0.1.2 → onvif_python-0.1.4}/onvif/wsdl/ver10/credential/wsdl/credential.wsdl +0 -0
  71. {onvif_python-0.1.2 → onvif_python-0.1.4}/onvif/wsdl/ver10/credential/wsdl/index.html +0 -0
  72. {onvif_python-0.1.2 → onvif_python-0.1.4}/onvif/wsdl/ver10/device/wsdl/devicemgmt.wsdl +0 -0
  73. {onvif_python-0.1.2 → onvif_python-0.1.4}/onvif/wsdl/ver10/deviceio.wsdl +0 -0
  74. {onvif_python-0.1.2 → onvif_python-0.1.4}/onvif/wsdl/ver10/display/display.wsdl +0 -0
  75. {onvif_python-0.1.2 → onvif_python-0.1.4}/onvif/wsdl/ver10/display/wsdl/index.htm +0 -0
  76. {onvif_python-0.1.2 → onvif_python-0.1.4}/onvif/wsdl/ver10/display.wsdl +0 -0
  77. {onvif_python-0.1.2 → onvif_python-0.1.4}/onvif/wsdl/ver10/doorcontrol/wsdl/index.html +0 -0
  78. {onvif_python-0.1.2 → onvif_python-0.1.4}/onvif/wsdl/ver10/events/wsdl/bw-2-vs-mod.wsdl +0 -0
  79. {onvif_python-0.1.2 → onvif_python-0.1.4}/onvif/wsdl/ver10/events/wsdl/event-vs.wsdl +0 -0
  80. {onvif_python-0.1.2 → onvif_python-0.1.4}/onvif/wsdl/ver10/events/wsdl/event.wsdl +0 -0
  81. {onvif_python-0.1.2 → onvif_python-0.1.4}/onvif/wsdl/ver10/events/wsdl/index.html +0 -0
  82. {onvif_python-0.1.2 → onvif_python-0.1.4}/onvif/wsdl/ver10/federatedsearch.wsdl +0 -0
  83. {onvif_python-0.1.2 → onvif_python-0.1.4}/onvif/wsdl/ver10/media/wsdl/media.wsdl +0 -0
  84. {onvif_python-0.1.2 → onvif_python-0.1.4}/onvif/wsdl/ver10/pacs/accesscontrol.wsdl +0 -0
  85. {onvif_python-0.1.2 → onvif_python-0.1.4}/onvif/wsdl/ver10/pacs/doorcontrol.wsdl +0 -0
  86. {onvif_python-0.1.2 → onvif_python-0.1.4}/onvif/wsdl/ver10/pacs/types.xsd +0 -0
  87. {onvif_python-0.1.2 → onvif_python-0.1.4}/onvif/wsdl/ver10/provisioning/wsdl/provisioning.wsdl +0 -0
  88. {onvif_python-0.1.2 → onvif_python-0.1.4}/onvif/wsdl/ver10/receiver.wsdl +0 -0
  89. {onvif_python-0.1.2 → onvif_python-0.1.4}/onvif/wsdl/ver10/recording.wsdl +0 -0
  90. {onvif_python-0.1.2 → onvif_python-0.1.4}/onvif/wsdl/ver10/replay.wsdl +0 -0
  91. {onvif_python-0.1.2 → onvif_python-0.1.4}/onvif/wsdl/ver10/schedule/wsdl/index.html +0 -0
  92. {onvif_python-0.1.2 → onvif_python-0.1.4}/onvif/wsdl/ver10/schedule/wsdl/schedule.wsdl +0 -0
  93. {onvif_python-0.1.2 → onvif_python-0.1.4}/onvif/wsdl/ver10/schema/common.xsd +0 -0
  94. {onvif_python-0.1.2 → onvif_python-0.1.4}/onvif/wsdl/ver10/schema/metadatastream.xsd +0 -0
  95. {onvif_python-0.1.2 → onvif_python-0.1.4}/onvif/wsdl/ver10/schema/onvif.xsd +0 -0
  96. {onvif_python-0.1.2 → onvif_python-0.1.4}/onvif/wsdl/ver10/search.wsdl +0 -0
  97. {onvif_python-0.1.2 → onvif_python-0.1.4}/onvif/wsdl/ver10/thermal/wsdl/index.html +0 -0
  98. {onvif_python-0.1.2 → onvif_python-0.1.4}/onvif/wsdl/ver10/thermal/wsdl/thermal.wsdl +0 -0
  99. {onvif_python-0.1.2 → onvif_python-0.1.4}/onvif/wsdl/ver10/topics/topicns.xml +0 -0
  100. {onvif_python-0.1.2 → onvif_python-0.1.4}/onvif/wsdl/ver10/uplink/wsdl/index.html +0 -0
  101. {onvif_python-0.1.2 → onvif_python-0.1.4}/onvif/wsdl/ver10/uplink/wsdl/uplink.wsdl +0 -0
  102. {onvif_python-0.1.2 → onvif_python-0.1.4}/onvif/wsdl/ver20/analytics/humanbody.xsd +0 -0
  103. {onvif_python-0.1.2 → onvif_python-0.1.4}/onvif/wsdl/ver20/analytics/humanface.xsd +0 -0
  104. {onvif_python-0.1.2 → onvif_python-0.1.4}/onvif/wsdl/ver20/analytics/index.html +0 -0
  105. {onvif_python-0.1.2 → onvif_python-0.1.4}/onvif/wsdl/ver20/analytics/radiometry.xsd +0 -0
  106. {onvif_python-0.1.2 → onvif_python-0.1.4}/onvif/wsdl/ver20/analytics/rules.xsd +0 -0
  107. {onvif_python-0.1.2 → onvif_python-0.1.4}/onvif/wsdl/ver20/analytics/wsdl/analytics.wsdl +0 -0
  108. {onvif_python-0.1.2 → onvif_python-0.1.4}/onvif/wsdl/ver20/analytics/wsdl/index.html +0 -0
  109. {onvif_python-0.1.2 → onvif_python-0.1.4}/onvif/wsdl/ver20/imaging/wsdl/imaging.wsdl +0 -0
  110. {onvif_python-0.1.2 → onvif_python-0.1.4}/onvif/wsdl/ver20/media/wsdl/index.html +0 -0
  111. {onvif_python-0.1.2 → onvif_python-0.1.4}/onvif/wsdl/ver20/media/wsdl/media.wsdl +0 -0
  112. {onvif_python-0.1.2 → onvif_python-0.1.4}/onvif/wsdl/ver20/ptz/wsdl/ptz.wsdl +0 -0
  113. {onvif_python-0.1.2 → onvif_python-0.1.4}/onvif/wsdl/ver20/util/federated_search_documentation.html +0 -0
  114. {onvif_python-0.1.2 → onvif_python-0.1.4}/onvif/wsdl/ver20/util/fedsearch-docu-viewer.xsl +0 -0
  115. {onvif_python-0.1.2 → onvif_python-0.1.4}/onvif/wsdl/ver20/util/onvif-wsdl-viewer.xsl +0 -0
  116. {onvif_python-0.1.2 → onvif_python-0.1.4}/onvif/wsdl/ver20/util/operationIndex.html +0 -0
  117. {onvif_python-0.1.2 → onvif_python-0.1.4}/onvif_python.egg-info/SOURCES.txt +0 -0
  118. {onvif_python-0.1.2 → onvif_python-0.1.4}/onvif_python.egg-info/dependency_links.txt +0 -0
  119. {onvif_python-0.1.2 → onvif_python-0.1.4}/onvif_python.egg-info/entry_points.txt +0 -0
  120. {onvif_python-0.1.2 → onvif_python-0.1.4}/onvif_python.egg-info/requires.txt +0 -0
  121. {onvif_python-0.1.2 → onvif_python-0.1.4}/onvif_python.egg-info/top_level.txt +0 -0
  122. {onvif_python-0.1.2 → onvif_python-0.1.4}/setup.cfg +0 -0
  123. {onvif_python-0.1.2 → onvif_python-0.1.4}/setup.py +0 -0
  124. {onvif_python-0.1.2 → onvif_python-0.1.4}/tests/test_client.py +0 -0
  125. {onvif_python-0.1.2 → onvif_python-0.1.4}/tests/test_core.py +0 -0
  126. {onvif_python-0.1.2 → onvif_python-0.1.4}/tests/test_error_handlers.py +0 -0
  127. {onvif_python-0.1.2 → onvif_python-0.1.4}/tests/test_exceptions.py +0 -0
  128. {onvif_python-0.1.2 → onvif_python-0.1.4}/tests/test_wsdl_map.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: onvif-python
3
- Version: 0.1.2
3
+ Version: 0.1.4
4
4
  Summary: A comprehensive and developer-friendly Python library for working with ONVIF-compliant devices
5
5
  Author-email: Nirsimetri Technologies® <open@nirsimetri.com>
6
6
  Maintainer: Kaburagi
@@ -39,9 +39,9 @@ Dynamic: license-file
39
39
  # ONVIF Python
40
40
 
41
41
  [![License](https://img.shields.io/badge/License-MIT-blue)](https://github.com/nirsimetri/onvif-python?tab=MIT-1-ov-file)
42
- [![DeepWiki](https://img.shields.io/badge/DeepWiki-AI%20Wiki-orange)](https://deepwiki.com/nirsimetri/onvif-python)
43
- [![PyPI](https://img.shields.io/badge/PyPI-0.1.2-yellow?logo=archive)](https://pypi.org/project/onvif-python/)
44
- [![Downloads](https://img.shields.io/pypi/dm/onvif-python?label=PyPI%20Downloads)](https://clickpy.clickhouse.com/dashboard/onvif-python)
42
+ [![Ask DeepWiki](https://deepwiki.com/badge.svg)](https://deepwiki.com/nirsimetri/onvif-python)
43
+ [![PyPI](https://img.shields.io/badge/PyPI-0.1.4-orange?logo=archive)](https://pypi.org/project/onvif-python/)
44
+ [![Downloads](https://img.shields.io/pypi/dm/onvif-python?label=Downloads&color=red)](https://clickpy.clickhouse.com/dashboard/onvif-python)
45
45
  <br>
46
46
  [![Build](https://github.com/nirsimetri/onvif-python/actions/workflows/python-app.yml/badge.svg?branch=main)](https://github.com/nirsimetri/onvif-python/actions/workflows/python-app.yml)
47
47
  [![Upload Python Package](https://github.com/nirsimetri/onvif-python/actions/workflows/python-publish.yml/badge.svg)](https://github.com/nirsimetri/onvif-python/actions/workflows/python-publish.yml)
@@ -186,12 +186,12 @@ This library includes a powerful command-line interface (CLI) for interacting wi
186
186
  <tr>
187
187
  <td width="34.2%">
188
188
  <a href="https://github.com/nirsimetri/onvif-python">
189
- <img src="./assets/onvif_cli.png" />
189
+ <img src="https://raw.githubusercontent.com/nirsimetri/onvif-python/refs/heads/main/assets/onvif_cli.png" />
190
190
  </a>
191
191
  </td>
192
192
  <td width="65.8%">
193
193
  <a href="https://github.com/nirsimetri/onvif-python">
194
- <img src="./assets/onvif_operations.png" />
194
+ <img src="https://raw.githubusercontent.com/nirsimetri/onvif-python/refs/heads/main/assets/onvif_operations.png" />
195
195
  </a>
196
196
  </td>
197
197
  </tr>
@@ -212,10 +212,10 @@ This library includes a powerful command-line interface (CLI) for interacting wi
212
212
 
213
213
  ```bash
214
214
  usage: onvif [-h] [--host HOST] [--port PORT] [--username USERNAME] [--password PASSWORD] [--discover] [--timeout TIMEOUT] [--https] [--no-verify]
215
- [--no-patch] [--interactive] [--debug] [--wsdl WSDL] [--cache {all,db,mem,none}]
215
+ [--no-patch] [--interactive] [--debug] [--wsdl WSDL] [--cache {all,db,mem,none}] [--version]
216
216
  [service] [method] [params ...]
217
217
 
218
- ONVIF Terminal Client —
218
+ ONVIF Terminal Client — v0.1.4
219
219
  https://github.com/nirsimetri/onvif-python
220
220
 
221
221
  positional arguments:
@@ -241,6 +241,7 @@ options:
241
241
  --wsdl WSDL Custom WSDL directory path
242
242
  --cache {all,db,mem,none}
243
243
  Caching mode for ONVIFClient (default: all). 'all': memory+disk, 'db': disk-only, 'mem': memory-only, 'none': disabled.
244
+ --version, -v Show ONVIF CLI version and exit
244
245
 
245
246
  Examples:
246
247
  # Discover ONVIF devices on network
@@ -269,7 +270,7 @@ Examples:
269
270
  <summary><b>2. Interactive Shell</b></summary>
270
271
 
271
272
  ```bash
272
- ONVIF Interactive Shell Commands -
273
+ ONVIF Interactive Shell Commands - v0.1.4
273
274
  https://github.com/nirsimetri/onvif-python
274
275
 
275
276
  Basic Commands:
@@ -286,7 +287,11 @@ Navigation Commands:
286
287
  up - Exit current service mode (go up one level)
287
288
  pwd - Show current service context
288
289
  clear - Clear terminal screen
289
- desc <method> - Show method documentation in service mode
290
+ help <command> - Show help for a specific command
291
+
292
+ Service Mode Commands:
293
+ desc <method> - Show method documentation
294
+ type <method> - Show input/output types from WSDL
290
295
 
291
296
  Method Execution:
292
297
  <method> - Execute method without parameters
@@ -374,6 +379,9 @@ onvif --discover --username admin --password admin123 --interactive
374
379
 
375
380
  # Short form
376
381
  onvif -d -u admin -p admin123 -i
382
+
383
+ # Discover and interactive (will prompt for credentials)
384
+ onvif -d -i
377
385
  ```
378
386
 
379
387
  **Discover and Execute Command:**
@@ -745,6 +753,9 @@ If your device is not listed right now, feel free to contribute your test result
745
753
 
746
754
  This library fully supports all major ONVIF Profiles listed below. Each profile represents a standardized set of features and use cases, ensuring interoperability between ONVIF-compliant devices and clients. You can use this library to integrate with devices and systems that implement any of these profiles.
747
755
 
756
+ <details>
757
+ <summary><b>ONVIF profiles list</b></summary>
758
+
748
759
  | Name | Specifications | Main Features | Typical Use Case | Support |
749
760
  |-----------|----------------|---------------|------------------|---------|
750
761
  | Profile_S | [Document](https://www.onvif.org/wp-content/uploads/2019/12/ONVIF_Profile_-S_Specification_v1-3.pdf) | Video streaming, PTZ, audio, multicasting | Network video transmitters (cameras) and receivers (recorders, VMS) | ✅ Yes |
@@ -755,6 +766,8 @@ This library fully supports all major ONVIF Profiles listed below. Each profile
755
766
  | Profile_D | [Document](https://www.onvif.org/wp-content/uploads/2021/06/onvif-profile-d-specification-v1-0.pdf) | Access control peripherals (locks, sensors, relays) | Peripheral devices for access control | ✅ Yes |
756
767
  | Profile_M | [Document](https://www.onvif.org/wp-content/uploads/2024/04/onvif-profile-m-specification-v1-1.pdf) | Metadata, analytics events, object detection | Analytics devices, metadata clients | ✅ Yes |
757
768
 
769
+ </details>
770
+
758
771
  For a full description of each profile and its features, visit [ONVIF Profiles](https://www.onvif.org/profiles/).
759
772
 
760
773
  ## Implemented ONVIF Services
@@ -764,6 +777,9 @@ For a full description of each profile and its features, visit [ONVIF Profiles](
764
777
 
765
778
  Below is a list of ONVIF services implemented and supported by this library, along with links to the official specifications, service definitions, and schema files as referenced from the [ONVIF Developer Specs](https://developer.onvif.org/pub/specs/branches/development/doc/index.html). This table provides a quick overview of the available ONVIF features and their technical documentation for integration and development purposes.
766
779
 
780
+ <details>
781
+ <summary><b>ONVIF services list</b></summary>
782
+
767
783
  | Service | Specifications | Service Definitions | Schema Files | Status |
768
784
  |------------------------|-------------------------------|-----------------------------|-------------------------------------|------------|
769
785
  | Device Management | [Document](https://developer.onvif.org/pub/specs/branches/development/doc/Core.xml) | [device.wsdl](https://developer.onvif.org/pub/specs/branches/development/wsdl/ver10/device/wsdl/devicemgmt.wsdl) | [onvif.xsd](https://developer.onvif.org/pub/specs/branches/development/wsdl/ver10/schema/onvif.xsd) <br> [common.xsd](https://developer.onvif.org/pub/specs/branches/development/wsdl/ver10/schema/common.xsd) | ✅ Complete |
@@ -795,6 +811,8 @@ Below is a list of ONVIF services implemented and supported by this library, alo
795
811
  | Uplink | [Document](https://developer.onvif.org/pub/specs/branches/development/doc/Uplink.xml) | [uplink.wsdl](https://developer.onvif.org/pub/specs/branches/development/wsdl/ver10/uplink/wsdl/uplink.wsdl) | - | ✅ Complete |
796
812
  | WebRTC | [Document](https://developer.onvif.org/pub/specs/branches/development/doc/WebRTC.xml) | - | - | ❌ Any idea? |
797
813
 
814
+ </details>
815
+
798
816
  ## Service Bindings in ONVIF
799
817
 
800
818
  ONVIF services are defined by WSDL bindings. In this library, there are two main patterns:
@@ -1,9 +1,9 @@
1
1
  # ONVIF Python
2
2
 
3
3
  [![License](https://img.shields.io/badge/License-MIT-blue)](https://github.com/nirsimetri/onvif-python?tab=MIT-1-ov-file)
4
- [![DeepWiki](https://img.shields.io/badge/DeepWiki-AI%20Wiki-orange)](https://deepwiki.com/nirsimetri/onvif-python)
5
- [![PyPI](https://img.shields.io/badge/PyPI-0.1.2-yellow?logo=archive)](https://pypi.org/project/onvif-python/)
6
- [![Downloads](https://img.shields.io/pypi/dm/onvif-python?label=PyPI%20Downloads)](https://clickpy.clickhouse.com/dashboard/onvif-python)
4
+ [![Ask DeepWiki](https://deepwiki.com/badge.svg)](https://deepwiki.com/nirsimetri/onvif-python)
5
+ [![PyPI](https://img.shields.io/badge/PyPI-0.1.4-orange?logo=archive)](https://pypi.org/project/onvif-python/)
6
+ [![Downloads](https://img.shields.io/pypi/dm/onvif-python?label=Downloads&color=red)](https://clickpy.clickhouse.com/dashboard/onvif-python)
7
7
  <br>
8
8
  [![Build](https://github.com/nirsimetri/onvif-python/actions/workflows/python-app.yml/badge.svg?branch=main)](https://github.com/nirsimetri/onvif-python/actions/workflows/python-app.yml)
9
9
  [![Upload Python Package](https://github.com/nirsimetri/onvif-python/actions/workflows/python-publish.yml/badge.svg)](https://github.com/nirsimetri/onvif-python/actions/workflows/python-publish.yml)
@@ -148,12 +148,12 @@ This library includes a powerful command-line interface (CLI) for interacting wi
148
148
  <tr>
149
149
  <td width="34.2%">
150
150
  <a href="https://github.com/nirsimetri/onvif-python">
151
- <img src="./assets/onvif_cli.png" />
151
+ <img src="https://raw.githubusercontent.com/nirsimetri/onvif-python/refs/heads/main/assets/onvif_cli.png" />
152
152
  </a>
153
153
  </td>
154
154
  <td width="65.8%">
155
155
  <a href="https://github.com/nirsimetri/onvif-python">
156
- <img src="./assets/onvif_operations.png" />
156
+ <img src="https://raw.githubusercontent.com/nirsimetri/onvif-python/refs/heads/main/assets/onvif_operations.png" />
157
157
  </a>
158
158
  </td>
159
159
  </tr>
@@ -174,10 +174,10 @@ This library includes a powerful command-line interface (CLI) for interacting wi
174
174
 
175
175
  ```bash
176
176
  usage: onvif [-h] [--host HOST] [--port PORT] [--username USERNAME] [--password PASSWORD] [--discover] [--timeout TIMEOUT] [--https] [--no-verify]
177
- [--no-patch] [--interactive] [--debug] [--wsdl WSDL] [--cache {all,db,mem,none}]
177
+ [--no-patch] [--interactive] [--debug] [--wsdl WSDL] [--cache {all,db,mem,none}] [--version]
178
178
  [service] [method] [params ...]
179
179
 
180
- ONVIF Terminal Client —
180
+ ONVIF Terminal Client — v0.1.4
181
181
  https://github.com/nirsimetri/onvif-python
182
182
 
183
183
  positional arguments:
@@ -203,6 +203,7 @@ options:
203
203
  --wsdl WSDL Custom WSDL directory path
204
204
  --cache {all,db,mem,none}
205
205
  Caching mode for ONVIFClient (default: all). 'all': memory+disk, 'db': disk-only, 'mem': memory-only, 'none': disabled.
206
+ --version, -v Show ONVIF CLI version and exit
206
207
 
207
208
  Examples:
208
209
  # Discover ONVIF devices on network
@@ -231,7 +232,7 @@ Examples:
231
232
  <summary><b>2. Interactive Shell</b></summary>
232
233
 
233
234
  ```bash
234
- ONVIF Interactive Shell Commands -
235
+ ONVIF Interactive Shell Commands - v0.1.4
235
236
  https://github.com/nirsimetri/onvif-python
236
237
 
237
238
  Basic Commands:
@@ -248,7 +249,11 @@ Navigation Commands:
248
249
  up - Exit current service mode (go up one level)
249
250
  pwd - Show current service context
250
251
  clear - Clear terminal screen
251
- desc <method> - Show method documentation in service mode
252
+ help <command> - Show help for a specific command
253
+
254
+ Service Mode Commands:
255
+ desc <method> - Show method documentation
256
+ type <method> - Show input/output types from WSDL
252
257
 
253
258
  Method Execution:
254
259
  <method> - Execute method without parameters
@@ -336,6 +341,9 @@ onvif --discover --username admin --password admin123 --interactive
336
341
 
337
342
  # Short form
338
343
  onvif -d -u admin -p admin123 -i
344
+
345
+ # Discover and interactive (will prompt for credentials)
346
+ onvif -d -i
339
347
  ```
340
348
 
341
349
  **Discover and Execute Command:**
@@ -707,6 +715,9 @@ If your device is not listed right now, feel free to contribute your test result
707
715
 
708
716
  This library fully supports all major ONVIF Profiles listed below. Each profile represents a standardized set of features and use cases, ensuring interoperability between ONVIF-compliant devices and clients. You can use this library to integrate with devices and systems that implement any of these profiles.
709
717
 
718
+ <details>
719
+ <summary><b>ONVIF profiles list</b></summary>
720
+
710
721
  | Name | Specifications | Main Features | Typical Use Case | Support |
711
722
  |-----------|----------------|---------------|------------------|---------|
712
723
  | Profile_S | [Document](https://www.onvif.org/wp-content/uploads/2019/12/ONVIF_Profile_-S_Specification_v1-3.pdf) | Video streaming, PTZ, audio, multicasting | Network video transmitters (cameras) and receivers (recorders, VMS) | ✅ Yes |
@@ -717,6 +728,8 @@ This library fully supports all major ONVIF Profiles listed below. Each profile
717
728
  | Profile_D | [Document](https://www.onvif.org/wp-content/uploads/2021/06/onvif-profile-d-specification-v1-0.pdf) | Access control peripherals (locks, sensors, relays) | Peripheral devices for access control | ✅ Yes |
718
729
  | Profile_M | [Document](https://www.onvif.org/wp-content/uploads/2024/04/onvif-profile-m-specification-v1-1.pdf) | Metadata, analytics events, object detection | Analytics devices, metadata clients | ✅ Yes |
719
730
 
731
+ </details>
732
+
720
733
  For a full description of each profile and its features, visit [ONVIF Profiles](https://www.onvif.org/profiles/).
721
734
 
722
735
  ## Implemented ONVIF Services
@@ -726,6 +739,9 @@ For a full description of each profile and its features, visit [ONVIF Profiles](
726
739
 
727
740
  Below is a list of ONVIF services implemented and supported by this library, along with links to the official specifications, service definitions, and schema files as referenced from the [ONVIF Developer Specs](https://developer.onvif.org/pub/specs/branches/development/doc/index.html). This table provides a quick overview of the available ONVIF features and their technical documentation for integration and development purposes.
728
741
 
742
+ <details>
743
+ <summary><b>ONVIF services list</b></summary>
744
+
729
745
  | Service | Specifications | Service Definitions | Schema Files | Status |
730
746
  |------------------------|-------------------------------|-----------------------------|-------------------------------------|------------|
731
747
  | Device Management | [Document](https://developer.onvif.org/pub/specs/branches/development/doc/Core.xml) | [device.wsdl](https://developer.onvif.org/pub/specs/branches/development/wsdl/ver10/device/wsdl/devicemgmt.wsdl) | [onvif.xsd](https://developer.onvif.org/pub/specs/branches/development/wsdl/ver10/schema/onvif.xsd) <br> [common.xsd](https://developer.onvif.org/pub/specs/branches/development/wsdl/ver10/schema/common.xsd) | ✅ Complete |
@@ -757,6 +773,8 @@ Below is a list of ONVIF services implemented and supported by this library, alo
757
773
  | Uplink | [Document](https://developer.onvif.org/pub/specs/branches/development/doc/Uplink.xml) | [uplink.wsdl](https://developer.onvif.org/pub/specs/branches/development/wsdl/ver10/uplink/wsdl/uplink.wsdl) | - | ✅ Complete |
758
774
  | WebRTC | [Document](https://developer.onvif.org/pub/specs/branches/development/doc/WebRTC.xml) | - | - | ❌ Any idea? |
759
775
 
776
+ </details>
777
+
760
778
  ## Service Bindings in ONVIF
761
779
 
762
780
  ONVIF services are defined by WSDL bindings. In this library, there are two main patterns:
@@ -3,6 +3,8 @@
3
3
  import cmd
4
4
  import sys
5
5
  import socket
6
+ import ssl
7
+ import os
6
8
  import threading
7
9
  import textwrap
8
10
  from datetime import datetime
@@ -21,6 +23,7 @@ from .utils import (
21
23
  format_capabilities_as_services,
22
24
  format_services_list,
23
25
  get_method_documentation,
26
+ get_operation_type_info,
24
27
  )
25
28
 
26
29
 
@@ -61,6 +64,7 @@ class InteractiveShell(cmd.Cmd):
61
64
  "pwd",
62
65
  "shortcuts",
63
66
  "desc",
67
+ "type",
64
68
  ]
65
69
 
66
70
  # For background health check
@@ -179,7 +183,7 @@ class InteractiveShell(cmd.Cmd):
179
183
  " / __ \\/ | / / | / / _/ ____/",
180
184
  " / / / / |/ /| | / // // /_ ",
181
185
  "/ /_/ / /| / | |/ // // __/ ",
182
- "\\____/_/ |_/ |___/___/_/ v0.1.2",
186
+ "\\____/_/ |_/ |___/___/_/ v0.1.4",
183
187
  " ",
184
188
  ]
185
189
 
@@ -218,22 +222,39 @@ class InteractiveShell(cmd.Cmd):
218
222
  self._health_check_thread.start()
219
223
 
220
224
  def _periodic_health_check(self):
221
- """Periodically checks device connection using a TCP socket ping."""
222
- # Wait a moment before the first check to allow the shell to display the intro
225
+ """Periodically checks device connection using TCP or TLS depending on mode."""
226
+ # Wait before first check to allow intro to finish
223
227
  self._stop_health_check.wait(10.0)
228
+
224
229
  while not self._stop_health_check.is_set():
225
230
  sock = None
226
231
  try:
227
- # Create a socket and set a short timeout
228
- sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
229
- sock.settimeout(3) # 3-second timeout for the connection attempt
232
+ sock = socket.create_connection(
233
+ (self.args.host, self.args.port), timeout=5.0
234
+ )
235
+
236
+ # If HTTPS, perform a short TLS handshake check
237
+ if getattr(self.args, "https", False):
238
+ context = ssl.create_default_context()
239
+ context.check_hostname = False
240
+ context.verify_mode = ssl.CERT_NONE
241
+
242
+ with context.wrap_socket(
243
+ sock, server_hostname=self.args.host
244
+ ) as ssock:
245
+ ssock.settimeout(5)
246
+ # Try a minimal handshake
247
+ ssock.do_handshake()
248
+
249
+ # If we reach here, the connection (and TLS if applicable) succeeded
250
+ pass
230
251
 
231
- # Try to connect to the host and port
232
- sock.connect((self.args.host, self.args.port))
233
252
  except (
234
253
  socket.timeout,
235
254
  ConnectionRefusedError,
236
255
  socket.gaierror,
256
+ ssl.SSLError,
257
+ ssl.SSLEOFError,
237
258
  OSError,
238
259
  ) as e:
239
260
  # Connection failed, trigger exit
@@ -242,7 +263,7 @@ class InteractiveShell(cmd.Cmd):
242
263
  file=sys.stderr,
243
264
  )
244
265
  print(
245
- f"{colorize('Error:', 'red')} TCP check failed - {e}",
266
+ f"{colorize('Error:', 'red')} Health check failed: {e}",
246
267
  file=sys.stderr,
247
268
  )
248
269
  print(
@@ -251,15 +272,13 @@ class InteractiveShell(cmd.Cmd):
251
272
  )
252
273
  # Forcibly exit the entire process. This is necessary to interrupt
253
274
  # the blocking input() call in the main thread.
254
- import os
255
-
256
275
  os._exit(1)
257
276
  finally:
258
277
  # Ensure the socket is always closed
259
278
  if sock:
260
279
  sock.close()
261
280
 
262
- # Wait for the next interval or until stopped
281
+ # Wait before next check or stop signal
263
282
  self._stop_health_check.wait(5.0) # Check every 5 seconds
264
283
 
265
284
  def _handle_connection_error(self, e):
@@ -766,8 +785,9 @@ class InteractiveShell(cmd.Cmd):
766
785
 
767
786
  if not self.current_service:
768
787
  print(
769
- f"{colorize('Error:', 'red')} This command can only be used within a service context."
788
+ f"{colorize('Error:', 'red')} You must be in a service mode to use 'desc'."
770
789
  )
790
+ print(f"Enter a service first (e.g., {colorize('devicemgmt', 'yellow')})")
771
791
  return
772
792
 
773
793
  if not method_name:
@@ -808,8 +828,175 @@ class InteractiveShell(cmd.Cmd):
808
828
  f"No documentation or parameter info found for method '{method_name}'."
809
829
  )
810
830
 
811
- def help_desc(self):
812
- print(self.do_desc.__doc__)
831
+ def complete_desc(self, text, line, begidx, endidx):
832
+ """Autocomplete method names for desc command"""
833
+ if not self.current_service:
834
+ return []
835
+ methods = get_service_methods(self.current_service)
836
+ return [m for m in methods if m.lower().startswith(text.lower())]
837
+
838
+ def do_type(self, line):
839
+ """Show input and output types for an operation. Usage: type <operation_name>"""
840
+ operation_name = line.strip()
841
+
842
+ if not self.current_service:
843
+ print(
844
+ f"{colorize('Error:', 'red')} You must be in a service mode to use 'type'."
845
+ )
846
+ print(f"Enter a service first (e.g., {colorize('d', 'yellow')})")
847
+ return
848
+
849
+ if not operation_name:
850
+ print(f"Usage: {colorize('type <operation_name>', 'yellow')}")
851
+ return
852
+
853
+ if not hasattr(self.current_service, operation_name):
854
+ print(
855
+ f"{colorize('Error:', 'red')} Operation '{operation_name}' not found in service '{self.current_service_name}'."
856
+ )
857
+ print(f"Use {colorize('ls', 'yellow')} to see available operations.")
858
+ return
859
+
860
+ type_info = get_operation_type_info(self.current_service, operation_name)
861
+
862
+ if type_info:
863
+ # Helper function to display parameters recursively with tree-style indentation
864
+ def display_params(params, prefix_lines=None, is_root_level=False):
865
+ """
866
+ Display parameters with tree-style formatting.
867
+
868
+ Args:
869
+ params: List of parameter dictionaries
870
+ prefix_lines: List of strings representing the tree prefix for each line
871
+ is_root_level: If True, don't show tree characters at this level
872
+ """
873
+ if prefix_lines is None:
874
+ prefix_lines = []
875
+
876
+ for idx, param in enumerate(params):
877
+ is_last = idx == len(params) - 1
878
+
879
+ # Determine tree characters (only if not root level)
880
+ if is_root_level:
881
+ tree_branch = ""
882
+ tree_continue = ""
883
+ else:
884
+ if is_last:
885
+ tree_branch = "└── "
886
+ tree_continue = " "
887
+ else:
888
+ tree_branch = "├── "
889
+ tree_continue = "│ "
890
+
891
+ # Determine prefix symbol: + for attributes, - for elements
892
+ prefix_symbol = "+" if param.get("is_attribute", False) else "-"
893
+
894
+ # Format occurrences based on type
895
+ occurs = ""
896
+ if param.get("is_attribute", False):
897
+ # For attributes: only show "required" if use="required"
898
+ # Default for attributes is optional (no label needed)
899
+ if param["minOccurs"] == "1": # This means use="required"
900
+ occurs = f" - {colorize('required', 'yellow')}"
901
+ # If minOccurs == "0", it's optional (default), so no label
902
+ else:
903
+ # For elements: show unbounded, optional, or required
904
+ if param["maxOccurs"] == "unbounded":
905
+ occurs = f" - {colorize('unbounded', 'magenta')}"
906
+ elif param["minOccurs"] == "0":
907
+ occurs = f" - {colorize('optional', 'green')}"
908
+ else:
909
+ occurs = f" - {colorize('required', 'yellow')}"
910
+
911
+ # Format type
912
+ type_str = f"[{param['type']}]" if param["type"] else ""
913
+
914
+ # Build the current line prefix from all previous levels
915
+ current_prefix = "".join(prefix_lines)
916
+
917
+ # Add spacing for root level items
918
+ if is_root_level:
919
+ current_prefix = " "
920
+
921
+ # Display parameter name with tree structure, prefix, occurrence, and type
922
+ # Only add semicolon separator if there's an occurrence label
923
+ separator = ";" if occurs else ""
924
+ param_line = f"{current_prefix}{tree_branch}{prefix_symbol}{colorize(param['name'], 'white')}{occurs}{separator} {colorize(type_str, 'cyan')}"
925
+ print(param_line)
926
+
927
+ # Display documentation if available
928
+ if param.get("documentation"):
929
+ doc_lines = param["documentation"].split("\n")
930
+ for doc_line in doc_lines:
931
+ if doc_line.strip():
932
+ # Add tree continuation for documentation
933
+ if is_root_level:
934
+ doc_prefix = " "
935
+ else:
936
+ doc_prefix = current_prefix + tree_continue
937
+ wrapped_doc = textwrap.fill(
938
+ doc_line.strip(),
939
+ width=96, # Slightly less to account for tree chars
940
+ initial_indent=doc_prefix + " ",
941
+ subsequent_indent=doc_prefix + " ",
942
+ )
943
+ print(colorize(wrapped_doc, "reset"))
944
+
945
+ # Display children recursively with updated prefix
946
+ if param.get("children"):
947
+ if is_root_level:
948
+ # Start tree structure from children
949
+ new_prefix_lines = [" "]
950
+ else:
951
+ new_prefix_lines = prefix_lines + [tree_continue]
952
+ display_params(
953
+ param["children"], new_prefix_lines, is_root_level=False
954
+ )
955
+
956
+ # Display Input
957
+ if type_info["input"]:
958
+ input_msg = type_info["input"]
959
+ print(f"\n{colorize('Input:', 'cyan')}")
960
+ msg_name = f"[{input_msg['name']}]"
961
+ print(f"{colorize(msg_name, 'yellow')}")
962
+
963
+ if input_msg["parameters"]:
964
+ display_params(input_msg["parameters"], is_root_level=True)
965
+ else:
966
+ print(f" {colorize('(no parameters)', 'reset')}")
967
+ else:
968
+ print(
969
+ f"\n{colorize('Input:', 'cyan')} {colorize('(not defined)', 'reset')}"
970
+ )
971
+
972
+ # Display Output
973
+ if type_info["output"]:
974
+ output_msg = type_info["output"]
975
+ print(f"\n{colorize('Output:', 'cyan')}")
976
+ msg_name = f"[{output_msg['name']}]"
977
+ print(f"{colorize(msg_name, 'yellow')}")
978
+
979
+ if output_msg["parameters"]:
980
+ display_params(output_msg["parameters"], is_root_level=True)
981
+ else:
982
+ print(f" {colorize('(no parameters)', 'reset')}")
983
+ else:
984
+ print(
985
+ f"\n{colorize('Output:', 'cyan')} {colorize('(not defined)', 'reset')}"
986
+ )
987
+
988
+ print() # Add newline for spacing
989
+ else:
990
+ print(
991
+ f"{colorize('Error:', 'red')} Could not retrieve type information for '{operation_name}'."
992
+ )
993
+
994
+ def complete_type(self, text, line, begidx, endidx):
995
+ """Autocomplete method names for type command"""
996
+ if not self.current_service:
997
+ return []
998
+ methods = get_service_methods(self.current_service)
999
+ return [m for m in methods if m.lower().startswith(text.lower())]
813
1000
 
814
1001
  def do_cd(self, line):
815
1002
  """Change to service directory (alias for entering service)"""
@@ -821,6 +1008,11 @@ class InteractiveShell(cmd.Cmd):
821
1008
  return
822
1009
  return self.do_enter_service(line)
823
1010
 
1011
+ def complete_cd(self, text, line, begidx, endidx):
1012
+ """Autocomplete service names for cd command"""
1013
+ services = get_device_available_services(self.client)
1014
+ return [s for s in services if s.lower().startswith(text.lower())]
1015
+
824
1016
  def do_pwd(self, line):
825
1017
  """Show current service context"""
826
1018
  if self.current_service_name:
@@ -844,7 +1036,11 @@ class InteractiveShell(cmd.Cmd):
844
1036
  up - Go up one level
845
1037
  pwd - Show current context
846
1038
  clear - Clear terminal screen
847
- desc <method> - Show method documentation in service mode
1039
+ help <command> - Show help for a command
1040
+
1041
+ {colorize('Service Mode Commands:', 'yellow')}
1042
+ desc <method> - Show method documentation
1043
+ type <method> - Show input/output types from WSDL
848
1044
 
849
1045
  {colorize('Quick Access:', 'yellow')}
850
1046
  caps - Show capabilities (same as 'capabilities')
@@ -925,6 +1121,10 @@ class InteractiveShell(cmd.Cmd):
925
1121
  else:
926
1122
  print(f"{colorize('Error:', 'red')} No stored data named '{line}'")
927
1123
 
1124
+ def complete_rm(self, text, line, begidx, endidx):
1125
+ """Autocomplete stored variable names for rm command"""
1126
+ return [name for name in self.stored_data.keys() if name.startswith(text)]
1127
+
928
1128
  def do_show(self, line):
929
1129
  """Show stored data: show <name> or show <name>.<attribute> or show <name>[index]"""
930
1130
  if not line:
@@ -947,10 +1147,17 @@ class InteractiveShell(cmd.Cmd):
947
1147
  else:
948
1148
  print(f"{colorize('Error:', 'red')} Cannot resolve '{line}'")
949
1149
 
1150
+ def complete_show(self, text, line, begidx, endidx):
1151
+ """Autocomplete stored variable names for show command"""
1152
+ # Get the part being completed
1153
+ parts = line.split()
1154
+ if len(parts) <= 1 or (len(parts) == 2 and not line.endswith(" ")):
1155
+ # Completing the variable name
1156
+ return [name for name in self.stored_data.keys() if name.startswith(text)]
1157
+ return []
1158
+
950
1159
  def do_clear(self, line):
951
1160
  """Clear terminal screen"""
952
- import os
953
-
954
1161
  # Clear screen for both Windows and Unix-like systems
955
1162
  os.system("cls" if os.name == "nt" else "clear")
956
1163
 
@@ -1093,7 +1300,7 @@ class InteractiveShell(cmd.Cmd):
1093
1300
  super().do_help(line)
1094
1301
  else:
1095
1302
  help_text = f"""
1096
- {colorize('ONVIF Interactive Shell Commands -', 'cyan')}\n{colorize('https://github.com/nirsimetri/onvif-python', 'white')}
1303
+ {colorize('ONVIF Interactive Shell Commands - v0.1.4', 'cyan')}\n{colorize('https://github.com/nirsimetri/onvif-python', 'white')}
1097
1304
 
1098
1305
  {colorize('Basic Commands:', 'yellow')}
1099
1306
  capabilities, caps - Show device capabilities
@@ -1109,7 +1316,11 @@ class InteractiveShell(cmd.Cmd):
1109
1316
  up - Exit current service mode (go up one level)
1110
1317
  pwd - Show current service context
1111
1318
  clear - Clear terminal screen
1112
- desc <method> - Show method documentation in service mode
1319
+ help <command> - Show help for a specific command
1320
+
1321
+ {colorize('Service Mode Commands:', 'yellow')}
1322
+ desc <method> - Show method documentation
1323
+ type <method> - Show input/output types from WSDL
1113
1324
 
1114
1325
  {colorize('Method Execution:', 'yellow')}
1115
1326
  <method> - Execute method without parameters