bbfmodels 0.2.1__tar.gz → 0.3.0__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 (584) hide show
  1. bbfmodels-0.3.0/.github/workflows/announce-release.yml +70 -0
  2. bbfmodels-0.3.0/.release-please-manifest.json +3 -0
  3. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/CHANGELOG.md +7 -0
  4. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/PKG-INFO +5 -2
  5. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/README.md +4 -1
  6. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/context/README.md +1 -0
  7. bbfmodels-0.3.0/context/decisions/0011-typed-paths-are-a-stub-over-the-schema.md +44 -0
  8. bbfmodels-0.3.0/docs/guides/paths.md +86 -0
  9. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/docs/guides/quickstart.md +12 -0
  10. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/docs/index.md +2 -2
  11. bbfmodels-0.3.0/hooks/announce.py +102 -0
  12. bbfmodels-0.3.0/hooks/test_announce.py +89 -0
  13. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/mkdocs.yml +1 -0
  14. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/pyproject.toml +1 -1
  15. bbfmodels-0.3.0/release-notes/0.3.0.md +4 -0
  16. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/__init__.py +1 -1
  17. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/generate.py +75 -17
  18. bbfmodels-0.3.0/src/bbfmodels/paths.py +154 -0
  19. bbfmodels-0.3.0/src/bbfmodels/tr098/paths.py +13 -0
  20. bbfmodels-0.3.0/src/bbfmodels/tr098/paths.pyi +2387 -0
  21. bbfmodels-0.3.0/src/bbfmodels/tr104_1/paths.py +13 -0
  22. bbfmodels-0.3.0/src/bbfmodels/tr104_1/paths.pyi +486 -0
  23. bbfmodels-0.3.0/src/bbfmodels/tr104_cwmp/paths.py +13 -0
  24. bbfmodels-0.3.0/src/bbfmodels/tr104_cwmp/paths.pyi +1195 -0
  25. bbfmodels-0.3.0/src/bbfmodels/tr104_usp/paths.py +13 -0
  26. bbfmodels-0.3.0/src/bbfmodels/tr104_usp/paths.pyi +1177 -0
  27. bbfmodels-0.3.0/src/bbfmodels/tr135_cwmp/paths.py +13 -0
  28. bbfmodels-0.3.0/src/bbfmodels/tr135_cwmp/paths.pyi +823 -0
  29. bbfmodels-0.3.0/src/bbfmodels/tr135_usp/paths.py +13 -0
  30. bbfmodels-0.3.0/src/bbfmodels/tr135_usp/paths.pyi +795 -0
  31. bbfmodels-0.3.0/src/bbfmodels/tr140_cwmp/paths.py +13 -0
  32. bbfmodels-0.3.0/src/bbfmodels/tr140_cwmp/paths.pyi +190 -0
  33. bbfmodels-0.3.0/src/bbfmodels/tr140_usp/paths.py +13 -0
  34. bbfmodels-0.3.0/src/bbfmodels/tr140_usp/paths.pyi +190 -0
  35. bbfmodels-0.3.0/src/bbfmodels/tr181_cwmp/paths.py +13 -0
  36. bbfmodels-0.3.0/src/bbfmodels/tr181_cwmp/paths.pyi +11041 -0
  37. bbfmodels-0.3.0/src/bbfmodels/tr181_usp/paths.py +13 -0
  38. bbfmodels-0.3.0/src/bbfmodels/tr181_usp/paths.pyi +10344 -0
  39. bbfmodels-0.3.0/src/bbfmodels/tr196_cwmp/paths.py +13 -0
  40. bbfmodels-0.3.0/src/bbfmodels/tr196_cwmp/paths.pyi +2476 -0
  41. bbfmodels-0.3.0/src/bbfmodels/tr196_usp/paths.py +13 -0
  42. bbfmodels-0.3.0/src/bbfmodels/tr196_usp/paths.pyi +2476 -0
  43. bbfmodels-0.3.0/src/bbfmodels/tr517_usp/paths.py +13 -0
  44. bbfmodels-0.3.0/src/bbfmodels/tr517_usp/paths.pyi +6314 -0
  45. bbfmodels-0.3.0/tests/test_paths.py +95 -0
  46. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/uv.lock +1 -1
  47. bbfmodels-0.2.1/.release-please-manifest.json +0 -3
  48. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/.github/workflows/ci.yml +0 -0
  49. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/.github/workflows/docs.yml +0 -0
  50. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/.github/workflows/pr-title.yml +0 -0
  51. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/.github/workflows/publish.yml +0 -0
  52. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/.github/workflows/release-please.yml +0 -0
  53. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/.gitignore +0 -0
  54. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/.python-version +0 -0
  55. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/CLAUDE.md +0 -0
  56. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/CONTRIBUTING.md +0 -0
  57. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/LICENSE +0 -0
  58. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/Makefile +0 -0
  59. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/NOTICE +0 -0
  60. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/context/decisions/0001-one-parser-one-ir-several-emitters.md +0 -0
  61. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/context/decisions/0002-names-stay-as-the-forum-wrote-them.md +0 -0
  62. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/context/decisions/0003-parse-the-flattened-full-documents.md +0 -0
  63. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/context/decisions/0004-generated-output-is-committed.md +0 -0
  64. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/context/decisions/0005-python-models-are-pydantic.md +0 -0
  65. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/context/decisions/0006-everything-optional-unknown-paths-kept.md +0 -0
  66. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/context/decisions/0007-vendor-extensions-are-overlays.md +0 -0
  67. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/context/decisions/0008-python-toolchain.md +0 -0
  68. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/context/decisions/0009-the-tree-keeps-wire-text.md +0 -0
  69. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/context/decisions/0010-generated-python-packages.md +0 -0
  70. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/docs/assets/images/ispx-icon.png +0 -0
  71. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/docs/assets/js/copy-code.js +0 -0
  72. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/docs/assets/js/powered-by.js +0 -0
  73. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/docs/assets/stylesheets/extra.css +0 -0
  74. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/docs/changelog.md +0 -0
  75. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/docs/guides/cli.md +0 -0
  76. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/docs/guides/documents.md +0 -0
  77. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/docs/guides/models.md +0 -0
  78. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/docs/guides/runtime.md +0 -0
  79. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/docs/guides/vendor-models.md +0 -0
  80. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/hooks/changelog.py +0 -0
  81. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/hooks/test_changelog.py +0 -0
  82. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/release-notes/0.1.0.md +0 -0
  83. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/release-notes/0.2.0.md +0 -0
  84. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/release-notes/0.2.1.md +0 -0
  85. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/release-please-config.json +0 -0
  86. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/requirements.txt +0 -0
  87. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/scripts/bootstrap.sh +0 -0
  88. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/cli.py +0 -0
  89. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/codec.py +0 -0
  90. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/ir.py +0 -0
  91. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/model.py +0 -0
  92. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/parser.py +0 -0
  93. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/py.typed +0 -0
  94. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/schema.py +0 -0
  95. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/sources.py +0 -0
  96. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr098/__init__.py +0 -0
  97. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr098/bulkdata.py +0 -0
  98. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr098/capabilities.py +0 -0
  99. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr098/captiveportal.py +0 -0
  100. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr098/deviceconfig.py +0 -0
  101. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr098/deviceinfo.py +0 -0
  102. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr098/dlna.py +0 -0
  103. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr098/dns.py +0 -0
  104. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr098/downloadavailability.py +0 -0
  105. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr098/downloaddiagnostics.py +0 -0
  106. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr098/fap.py +0 -0
  107. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr098/faultmgmt.py +0 -0
  108. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr098/firewall.py +0 -0
  109. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr098/internetgatewaydevice.py +0 -0
  110. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr098/ippingdiagnostics.py +0 -0
  111. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr098/ir.json.gz +0 -0
  112. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr098/lanconfigsecurity.py +0 -0
  113. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr098/landevice.py +0 -0
  114. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr098/laninterfaces.py +0 -0
  115. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr098/layer2bridging.py +0 -0
  116. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr098/layer3forwarding.py +0 -0
  117. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr098/managementserver.py +0 -0
  118. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr098/nslookupdiagnostics.py +0 -0
  119. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr098/periodicstatistics.py +0 -0
  120. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr098/queuemanagement.py +0 -0
  121. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr098/security.py +0 -0
  122. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr098/selftestdiagnostics.py +0 -0
  123. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr098/services.py +0 -0
  124. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr098/smartcardreader.py +0 -0
  125. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr098/softwaremodules.py +0 -0
  126. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr098/time.py +0 -0
  127. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr098/traceroutediagnostics.py +0 -0
  128. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr098/udpechoconfig.py +0 -0
  129. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr098/uploaddiagnostics.py +0 -0
  130. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr098/upnp.py +0 -0
  131. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr098/usbhosts.py +0 -0
  132. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr098/user.py +0 -0
  133. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr098/userinterface.py +0 -0
  134. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr098/wandevice.py +0 -0
  135. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr098/xmpp.py +0 -0
  136. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr104_1/__init__.py +0 -0
  137. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr104_1/capabilities.py +0 -0
  138. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr104_1/ir.json.gz +0 -0
  139. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr104_1/phyinterface.py +0 -0
  140. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr104_1/voiceprofile.py +0 -0
  141. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr104_1/voiceservice.py +0 -0
  142. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr104_cwmp/__init__.py +0 -0
  143. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr104_cwmp/callcontrol.py +0 -0
  144. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr104_cwmp/calllog.py +0 -0
  145. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr104_cwmp/capabilities.py +0 -0
  146. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr104_cwmp/clocksynchronization.py +0 -0
  147. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr104_cwmp/codecprofile.py +0 -0
  148. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr104_cwmp/dect.py +0 -0
  149. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr104_cwmp/h323.py +0 -0
  150. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr104_cwmp/interwork.py +0 -0
  151. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr104_cwmp/ir.json.gz +0 -0
  152. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr104_cwmp/isdn.py +0 -0
  153. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr104_cwmp/mgcp.py +0 -0
  154. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr104_cwmp/pots.py +0 -0
  155. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr104_cwmp/reservedports.py +0 -0
  156. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr104_cwmp/sip.py +0 -0
  157. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr104_cwmp/terminal.py +0 -0
  158. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr104_cwmp/tone.py +0 -0
  159. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr104_cwmp/trunk.py +0 -0
  160. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr104_cwmp/voiceservice.py +0 -0
  161. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr104_cwmp/voipprofile.py +0 -0
  162. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr104_usp/__init__.py +0 -0
  163. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr104_usp/callcontrol.py +0 -0
  164. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr104_usp/calllog.py +0 -0
  165. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr104_usp/capabilities.py +0 -0
  166. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr104_usp/clocksynchronization.py +0 -0
  167. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr104_usp/codecprofile.py +0 -0
  168. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr104_usp/dect.py +0 -0
  169. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr104_usp/h323.py +0 -0
  170. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr104_usp/interwork.py +0 -0
  171. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr104_usp/ir.json.gz +0 -0
  172. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr104_usp/isdn.py +0 -0
  173. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr104_usp/mgcp.py +0 -0
  174. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr104_usp/pots.py +0 -0
  175. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr104_usp/reservedports.py +0 -0
  176. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr104_usp/sip.py +0 -0
  177. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr104_usp/terminal.py +0 -0
  178. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr104_usp/tone.py +0 -0
  179. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr104_usp/trunk.py +0 -0
  180. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr104_usp/voiceservice.py +0 -0
  181. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr104_usp/voipprofile.py +0 -0
  182. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr135_cwmp/__init__.py +0 -0
  183. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr135_cwmp/applications.py +0 -0
  184. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr135_cwmp/avplayers.py +0 -0
  185. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr135_cwmp/avstreams.py +0 -0
  186. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr135_cwmp/capabilities.py +0 -0
  187. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr135_cwmp/components.py +0 -0
  188. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr135_cwmp/ir.json.gz +0 -0
  189. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr135_cwmp/servicemonitoring.py +0 -0
  190. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr135_cwmp/stbservice.py +0 -0
  191. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr135_usp/__init__.py +0 -0
  192. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr135_usp/applications.py +0 -0
  193. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr135_usp/avplayers.py +0 -0
  194. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr135_usp/avstreams.py +0 -0
  195. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr135_usp/capabilities.py +0 -0
  196. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr135_usp/components.py +0 -0
  197. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr135_usp/ir.json.gz +0 -0
  198. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr135_usp/servicemonitoring.py +0 -0
  199. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr135_usp/stbservice.py +0 -0
  200. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr140_cwmp/__init__.py +0 -0
  201. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr140_cwmp/capabilities.py +0 -0
  202. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr140_cwmp/ftpserver.py +0 -0
  203. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr140_cwmp/httpserver.py +0 -0
  204. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr140_cwmp/httpsserver.py +0 -0
  205. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr140_cwmp/ir.json.gz +0 -0
  206. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr140_cwmp/logicalvolume.py +0 -0
  207. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr140_cwmp/netinfo.py +0 -0
  208. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr140_cwmp/networkserver.py +0 -0
  209. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr140_cwmp/physicalmedium.py +0 -0
  210. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr140_cwmp/sftpserver.py +0 -0
  211. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr140_cwmp/storagearray.py +0 -0
  212. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr140_cwmp/storageservice.py +0 -0
  213. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr140_cwmp/useraccount.py +0 -0
  214. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr140_cwmp/usergroup.py +0 -0
  215. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr140_usp/__init__.py +0 -0
  216. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr140_usp/capabilities.py +0 -0
  217. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr140_usp/ftpserver.py +0 -0
  218. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr140_usp/httpserver.py +0 -0
  219. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr140_usp/httpsserver.py +0 -0
  220. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr140_usp/ir.json.gz +0 -0
  221. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr140_usp/logicalvolume.py +0 -0
  222. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr140_usp/netinfo.py +0 -0
  223. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr140_usp/networkserver.py +0 -0
  224. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr140_usp/physicalmedium.py +0 -0
  225. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr140_usp/sftpserver.py +0 -0
  226. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr140_usp/storagearray.py +0 -0
  227. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr140_usp/storageservice.py +0 -0
  228. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr140_usp/useraccount.py +0 -0
  229. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr140_usp/usergroup.py +0 -0
  230. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_cwmp/__init__.py +0 -0
  231. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_cwmp/atm.py +0 -0
  232. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_cwmp/basapm.py +0 -0
  233. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_cwmp/bridging.py +0 -0
  234. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_cwmp/bulkdata.py +0 -0
  235. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_cwmp/captiveportal.py +0 -0
  236. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_cwmp/cellular.py +0 -0
  237. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_cwmp/collectiondevice.py +0 -0
  238. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_cwmp/connectionmonitoring.py +0 -0
  239. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_cwmp/device.py +0 -0
  240. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_cwmp/deviceinfo.py +0 -0
  241. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_cwmp/dhcpv4.py +0 -0
  242. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_cwmp/dhcpv6.py +0 -0
  243. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_cwmp/dlna.py +0 -0
  244. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_cwmp/dns.py +0 -0
  245. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_cwmp/docsis.py +0 -0
  246. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_cwmp/dsl.py +0 -0
  247. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_cwmp/dslite.py +0 -0
  248. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_cwmp/dynamicdns.py +0 -0
  249. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_cwmp/ethernet.py +0 -0
  250. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_cwmp/etsim2m.py +0 -0
  251. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_cwmp/fap.py +0 -0
  252. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_cwmp/fast.py +0 -0
  253. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_cwmp/faultmgmt.py +0 -0
  254. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_cwmp/firewall.py +0 -0
  255. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_cwmp/fwe.py +0 -0
  256. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_cwmp/gatewayinfo.py +0 -0
  257. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_cwmp/ghn.py +0 -0
  258. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_cwmp/gre.py +0 -0
  259. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_cwmp/hardware.py +0 -0
  260. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_cwmp/homeplug.py +0 -0
  261. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_cwmp/hosts.py +0 -0
  262. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_cwmp/hpna.py +0 -0
  263. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_cwmp/ieee1905.py +0 -0
  264. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_cwmp/ieee8021x.py +0 -0
  265. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_cwmp/interfacestack.py +0 -0
  266. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_cwmp/ip.py +0 -0
  267. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_cwmp/ipsec.py +0 -0
  268. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_cwmp/ipv6rd.py +0 -0
  269. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_cwmp/ir.json.gz +0 -0
  270. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_cwmp/l2tpv3.py +0 -0
  271. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_cwmp/lanconfigsecurity.py +0 -0
  272. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_cwmp/leds.py +0 -0
  273. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_cwmp/lldp.py +0 -0
  274. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_cwmp/lmap.py +0 -0
  275. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_cwmp/logical.py +0 -0
  276. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_cwmp/managementserver.py +0 -0
  277. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_cwmp/map.py +0 -0
  278. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_cwmp/moca.py +0 -0
  279. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_cwmp/mqtt.py +0 -0
  280. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_cwmp/nat.py +0 -0
  281. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_cwmp/neighbordiscovery.py +0 -0
  282. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_cwmp/optical.py +0 -0
  283. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_cwmp/packetcapturediagnostics.py +0 -0
  284. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_cwmp/pcp.py +0 -0
  285. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_cwmp/pdu.py +0 -0
  286. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_cwmp/periodicfiletransfer.py +0 -0
  287. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_cwmp/periodicstatistics.py +0 -0
  288. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_cwmp/ppp.py +0 -0
  289. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_cwmp/ptm.py +0 -0
  290. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_cwmp/qos.py +0 -0
  291. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_cwmp/radsecproxy.py +0 -0
  292. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_cwmp/routeradvertisement.py +0 -0
  293. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_cwmp/routing.py +0 -0
  294. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_cwmp/schedules.py +0 -0
  295. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_cwmp/security.py +0 -0
  296. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_cwmp/selftestdiagnostics.py +0 -0
  297. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_cwmp/services.py +0 -0
  298. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_cwmp/sessionmanagement.py +0 -0
  299. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_cwmp/sfps.py +0 -0
  300. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_cwmp/smartcardreaders.py +0 -0
  301. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_cwmp/softwaremodules.py +0 -0
  302. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_cwmp/ssh.py +0 -0
  303. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_cwmp/stomp.py +0 -0
  304. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_cwmp/syslog.py +0 -0
  305. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_cwmp/thread.py +0 -0
  306. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_cwmp/time.py +0 -0
  307. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_cwmp/trustedelements.py +0 -0
  308. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_cwmp/unixdomainsockets.py +0 -0
  309. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_cwmp/upa.py +0 -0
  310. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_cwmp/upnp.py +0 -0
  311. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_cwmp/usb.py +0 -0
  312. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_cwmp/userinterface.py +0 -0
  313. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_cwmp/users.py +0 -0
  314. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_cwmp/uspagent.py +0 -0
  315. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_cwmp/uspservices.py +0 -0
  316. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_cwmp/vxlan.py +0 -0
  317. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_cwmp/wifi.py +0 -0
  318. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_cwmp/wireguard.py +0 -0
  319. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_cwmp/wwc.py +0 -0
  320. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_cwmp/xmpp.py +0 -0
  321. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_cwmp/xpon.py +0 -0
  322. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_cwmp/zigbee.py +0 -0
  323. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_usp/__init__.py +0 -0
  324. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_usp/atm.py +0 -0
  325. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_usp/basapm.py +0 -0
  326. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_usp/bridging.py +0 -0
  327. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_usp/bulkdata.py +0 -0
  328. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_usp/captiveportal.py +0 -0
  329. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_usp/cellular.py +0 -0
  330. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_usp/collectiondevice.py +0 -0
  331. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_usp/connectionmonitoring.py +0 -0
  332. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_usp/cwmpmanagementserver.py +0 -0
  333. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_usp/device.py +0 -0
  334. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_usp/deviceinfo.py +0 -0
  335. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_usp/dhcpv4.py +0 -0
  336. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_usp/dhcpv6.py +0 -0
  337. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_usp/dlna.py +0 -0
  338. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_usp/dns.py +0 -0
  339. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_usp/docsis.py +0 -0
  340. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_usp/dsl.py +0 -0
  341. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_usp/dslite.py +0 -0
  342. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_usp/dynamicdns.py +0 -0
  343. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_usp/ethernet.py +0 -0
  344. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_usp/fap.py +0 -0
  345. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_usp/fast.py +0 -0
  346. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_usp/faultmgmt.py +0 -0
  347. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_usp/firewall.py +0 -0
  348. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_usp/fwe.py +0 -0
  349. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_usp/gatewayinfo.py +0 -0
  350. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_usp/ghn.py +0 -0
  351. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_usp/gre.py +0 -0
  352. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_usp/hardware.py +0 -0
  353. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_usp/homeplug.py +0 -0
  354. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_usp/hosts.py +0 -0
  355. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_usp/hpna.py +0 -0
  356. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_usp/ieee1905.py +0 -0
  357. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_usp/ieee8021x.py +0 -0
  358. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_usp/interfacestack.py +0 -0
  359. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_usp/iotcapability.py +0 -0
  360. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_usp/ip.py +0 -0
  361. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_usp/ipsec.py +0 -0
  362. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_usp/ipv6rd.py +0 -0
  363. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_usp/ir.json.gz +0 -0
  364. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_usp/l2tpv3.py +0 -0
  365. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_usp/lanconfigsecurity.py +0 -0
  366. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_usp/leds.py +0 -0
  367. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_usp/lldp.py +0 -0
  368. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_usp/lmap.py +0 -0
  369. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_usp/localagent.py +0 -0
  370. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_usp/logical.py +0 -0
  371. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_usp/map.py +0 -0
  372. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_usp/moca.py +0 -0
  373. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_usp/mqtt.py +0 -0
  374. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_usp/nat.py +0 -0
  375. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_usp/neighbordiscovery.py +0 -0
  376. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_usp/node.py +0 -0
  377. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_usp/optical.py +0 -0
  378. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_usp/pcp.py +0 -0
  379. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_usp/pdu.py +0 -0
  380. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_usp/periodicfiletransfer.py +0 -0
  381. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_usp/periodicstatistics.py +0 -0
  382. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_usp/ppp.py +0 -0
  383. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_usp/proxieddevice.py +0 -0
  384. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_usp/ptm.py +0 -0
  385. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_usp/qos.py +0 -0
  386. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_usp/radsecproxy.py +0 -0
  387. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_usp/routeradvertisement.py +0 -0
  388. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_usp/routing.py +0 -0
  389. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_usp/schedules.py +0 -0
  390. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_usp/security.py +0 -0
  391. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_usp/services.py +0 -0
  392. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_usp/sessionmanagement.py +0 -0
  393. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_usp/sfps.py +0 -0
  394. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_usp/smartcardreaders.py +0 -0
  395. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_usp/softwaremodules.py +0 -0
  396. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_usp/ssh.py +0 -0
  397. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_usp/standby.py +0 -0
  398. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_usp/stomp.py +0 -0
  399. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_usp/syslog.py +0 -0
  400. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_usp/thread.py +0 -0
  401. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_usp/time.py +0 -0
  402. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_usp/trustedelements.py +0 -0
  403. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_usp/unixdomainsockets.py +0 -0
  404. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_usp/upa.py +0 -0
  405. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_usp/upnp.py +0 -0
  406. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_usp/usb.py +0 -0
  407. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_usp/userinterface.py +0 -0
  408. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_usp/users.py +0 -0
  409. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_usp/uspservices.py +0 -0
  410. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_usp/vxlan.py +0 -0
  411. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_usp/wifi.py +0 -0
  412. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_usp/wireguard.py +0 -0
  413. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_usp/wwc.py +0 -0
  414. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_usp/xmpp.py +0 -0
  415. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_usp/xpon.py +0 -0
  416. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_usp/zigbee.py +0 -0
  417. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr196_cwmp/__init__.py +0 -0
  418. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr196_cwmp/accessmgmt.py +0 -0
  419. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr196_cwmp/capabilities.py +0 -0
  420. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr196_cwmp/cellconfig.py +0 -0
  421. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr196_cwmp/fapcontrol.py +0 -0
  422. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr196_cwmp/fapservice.py +0 -0
  423. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr196_cwmp/ir.json.gz +0 -0
  424. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr196_cwmp/rem.py +0 -0
  425. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr196_cwmp/transport.py +0 -0
  426. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr196_usp/__init__.py +0 -0
  427. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr196_usp/accessmgmt.py +0 -0
  428. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr196_usp/capabilities.py +0 -0
  429. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr196_usp/cellconfig.py +0 -0
  430. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr196_usp/fapcontrol.py +0 -0
  431. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr196_usp/fapservice.py +0 -0
  432. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr196_usp/ir.json.gz +0 -0
  433. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr196_usp/rem.py +0 -0
  434. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr196_usp/transport.py +0 -0
  435. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/__init__.py +0 -0
  436. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/accesscontrolcluster.py +0 -0
  437. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/accountlogincluster.py +0 -0
  438. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/actionscluster.py +0 -0
  439. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/activatedcarbonfiltermonitoringcluster.py +0 -0
  440. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/administratorcommissioningcluster.py +0 -0
  441. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/airqualitycluster.py +0 -0
  442. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/applicationbasiccluster.py +0 -0
  443. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/applicationlaunchercluster.py +0 -0
  444. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/audiooutputcluster.py +0 -0
  445. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/basicinformationcluster.py +0 -0
  446. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/bindingcluster.py +0 -0
  447. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/booleanstatecluster.py +0 -0
  448. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/booleanstateconfigurationcluster.py +0 -0
  449. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/bridgeddevicebasicinformationcluster.py +0 -0
  450. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/cameraavsettingsuserlevelmanagementcluster.py +0 -0
  451. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/cameraavstreammanagementcluster.py +0 -0
  452. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/carbondioxideconcentrationmeasurementcluster.py +0 -0
  453. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/carbonmonoxideconcentrationmeasurementcluster.py +0 -0
  454. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/channelcluster.py +0 -0
  455. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/chimecluster.py +0 -0
  456. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/closurecontrolcluster.py +0 -0
  457. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/closuredimensioncluster.py +0 -0
  458. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/colorcontrolcluster.py +0 -0
  459. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/commissionercontrolcluster.py +0 -0
  460. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/commoditymeteringcluster.py +0 -0
  461. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/commoditypricecluster.py +0 -0
  462. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/commoditytariffcluster.py +0 -0
  463. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/contentappobservercluster.py +0 -0
  464. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/contentcontrolcluster.py +0 -0
  465. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/contentlaunchercluster.py +0 -0
  466. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/descriptorcluster.py +0 -0
  467. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/deviceenergymanagementcluster.py +0 -0
  468. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/deviceenergymanagementmodecluster.py +0 -0
  469. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/diagnosticlogscluster.py +0 -0
  470. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/dishwasheralarmcluster.py +0 -0
  471. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/dishwashermodecluster.py +0 -0
  472. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/doorlockcluster.py +0 -0
  473. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/ecosysteminformationcluster.py +0 -0
  474. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/electricalenergymeasurementcluster.py +0 -0
  475. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/electricalgridconditionscluster.py +0 -0
  476. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/electricalpowermeasurementcluster.py +0 -0
  477. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/endpoint.py +0 -0
  478. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/energyevsecluster.py +0 -0
  479. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/energyevsemodecluster.py +0 -0
  480. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/energypreferencecluster.py +0 -0
  481. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/ethernetnetworkdiagnosticscluster.py +0 -0
  482. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/fabric.py +0 -0
  483. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/fancontrolcluster.py +0 -0
  484. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/fixedlabelcluster.py +0 -0
  485. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/flowmeasurementcluster.py +0 -0
  486. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/formaldehydeconcentrationmeasurementcluster.py +0 -0
  487. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/generalcommissioningcluster.py +0 -0
  488. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/generaldiagnosticscluster.py +0 -0
  489. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/groupkeymanagementcluster.py +0 -0
  490. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/groupscluster.py +0 -0
  491. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/hepafiltermonitoringcluster.py +0 -0
  492. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/icdmanagementcluster.py +0 -0
  493. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/identifycluster.py +0 -0
  494. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/illuminancemeasurementcluster.py +0 -0
  495. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/ir.json.gz +0 -0
  496. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/jointfabricadministratorcluster.py +0 -0
  497. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/jointfabricdatastorecluster.py +0 -0
  498. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/keypadinputcluster.py +0 -0
  499. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/laundrydryercontrolscluster.py +0 -0
  500. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/laundrywashercontrolscluster.py +0 -0
  501. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/laundrywashermodecluster.py +0 -0
  502. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/levelcontrolcluster.py +0 -0
  503. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/localizationconfigurationcluster.py +0 -0
  504. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/lowpowercluster.py +0 -0
  505. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/matterservice.py +0 -0
  506. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/mediainputcluster.py +0 -0
  507. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/mediaplaybackcluster.py +0 -0
  508. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/messagescluster.py +0 -0
  509. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/meteridentificationcluster.py +0 -0
  510. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/microwaveovencontrolcluster.py +0 -0
  511. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/microwaveovenmodecluster.py +0 -0
  512. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/modeselectcluster.py +0 -0
  513. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/network.py +0 -0
  514. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/networkcommissioningcluster.py +0 -0
  515. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/nitrogendioxideconcentrationmeasurementcluster.py +0 -0
  516. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/occupancysensingcluster.py +0 -0
  517. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/onoffcluster.py +0 -0
  518. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/operationalcredentialscluster.py +0 -0
  519. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/operationalstatecluster.py +0 -0
  520. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/otasoftwareupdateprovidercluster.py +0 -0
  521. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/otasoftwareupdaterequestorcluster.py +0 -0
  522. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/ovencavityoperationalstatecluster.py +0 -0
  523. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/ovenmodecluster.py +0 -0
  524. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/ozoneconcentrationmeasurementcluster.py +0 -0
  525. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/pm10concentrationmeasurementcluster.py +0 -0
  526. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/pm1concentrationmeasurementcluster.py +0 -0
  527. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/pm25concentrationmeasurementcluster.py +0 -0
  528. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/powersourcecluster.py +0 -0
  529. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/powersourceconfigurationcluster.py +0 -0
  530. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/powertopologycluster.py +0 -0
  531. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/pressuremeasurementcluster.py +0 -0
  532. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/pumpconfigurationandcontrolcluster.py +0 -0
  533. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/pushavstreamtransportcluster.py +0 -0
  534. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/radonconcentrationmeasurementcluster.py +0 -0
  535. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/refrigeratoralarmcluster.py +0 -0
  536. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/refrigeratorandtemperaturecontrolledcabinetmodecluster.py +0 -0
  537. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/relativehumiditymeasurementcluster.py +0 -0
  538. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/rvccleanmodecluster.py +0 -0
  539. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/rvcoperationalstatecluster.py +0 -0
  540. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/rvcrunmodecluster.py +0 -0
  541. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/scenesmanagementcluster.py +0 -0
  542. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/serviceareacluster.py +0 -0
  543. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/smokecoalarmcluster.py +0 -0
  544. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/softwarediagnosticscluster.py +0 -0
  545. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/soilmeasurementcluster.py +0 -0
  546. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/switchcluster.py +0 -0
  547. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/targetnavigatorcluster.py +0 -0
  548. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/temperaturecontrolcluster.py +0 -0
  549. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/temperaturemeasurementcluster.py +0 -0
  550. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/thermostatcluster.py +0 -0
  551. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/thermostatuserinterfaceconfigurationcluster.py +0 -0
  552. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/threadborderroutermanagementcluster.py +0 -0
  553. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/threadnetworkdiagnosticscluster.py +0 -0
  554. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/threadnetworkdirectorycluster.py +0 -0
  555. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/timeformatlocalizationcluster.py +0 -0
  556. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/timesynchronizationcluster.py +0 -0
  557. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/tlscertificatemanagementcluster.py +0 -0
  558. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/tlsclientmanagementcluster.py +0 -0
  559. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/totalvolatileorganiccompoundsconcentrationmeasurementcluster.py +0 -0
  560. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/unitlocalizationcluster.py +0 -0
  561. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/userlabelcluster.py +0 -0
  562. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/valveconfigurationandcontrolcluster.py +0 -0
  563. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/wakeonlancluster.py +0 -0
  564. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/waterheatermanagementcluster.py +0 -0
  565. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/waterheatermodecluster.py +0 -0
  566. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/watertanklevelmonitoringcluster.py +0 -0
  567. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/webrtctransportprovidercluster.py +0 -0
  568. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/webrtctransportrequestorcluster.py +0 -0
  569. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/wifinetworkdiagnosticscluster.py +0 -0
  570. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/wifinetworkmanagementcluster.py +0 -0
  571. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/windowcoveringcluster.py +0 -0
  572. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/zonemanagementcluster.py +0 -0
  573. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tree.py +0 -0
  574. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/tests/fixtures/mini-cwmp-full.xml +0 -0
  575. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/tests/fixtures/mini-service-full.xml +0 -0
  576. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/tests/fixtures/mini-usp-full.xml +0 -0
  577. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/tests/test_cli.py +0 -0
  578. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/tests/test_codec.py +0 -0
  579. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/tests/test_documents.py +0 -0
  580. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/tests/test_generate.py +0 -0
  581. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/tests/test_parser.py +0 -0
  582. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/tests/test_schema.py +0 -0
  583. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/tests/test_tree.py +0 -0
  584. {bbfmodels-0.2.1 → bbfmodels-0.3.0}/wrangler.jsonc +0 -0
@@ -0,0 +1,70 @@
1
+ name: announce-release
2
+
3
+ # Posts a release's notes to the ispx Discord when they land on main.
4
+ # release-notes/<version>.md is written after the Release PR merges and
5
+ # lands by its own PR, so the notes file
6
+ # arriving on main is the moment the release is told, and only a file
7
+ # added by the push counts: an edit to existing notes is a wording fix,
8
+ # not a release. The dispatch input re-posts one version by hand, which
9
+ # is also how the webhook is tried out.
10
+ on:
11
+ push:
12
+ branches: [main]
13
+ paths:
14
+ - "release-notes/**"
15
+ workflow_dispatch:
16
+ inputs:
17
+ version:
18
+ description: Version whose notes to post, for example 0.2.1
19
+ required: true
20
+ type: string
21
+
22
+ permissions:
23
+ contents: read
24
+
25
+ concurrency:
26
+ group: announce-release
27
+ cancel-in-progress: false
28
+
29
+ jobs:
30
+ announce:
31
+ runs-on: ubuntu-latest
32
+ timeout-minutes: 5
33
+ steps:
34
+ - name: Checkout
35
+ uses: actions/checkout@v4
36
+
37
+ - name: Set up Python
38
+ uses: actions/setup-python@v5
39
+ with:
40
+ python-version: "3.12"
41
+
42
+ - name: Find the versions to post
43
+ id: versions
44
+ env:
45
+ BEFORE: ${{ github.event.before }}
46
+ REQUESTED: ${{ inputs.version }}
47
+ run: |
48
+ if [ -n "$REQUESTED" ]; then
49
+ versions="$REQUESTED"
50
+ else
51
+ git fetch --quiet --depth=1 origin "$BEFORE"
52
+ versions=$(git diff --name-only --diff-filter=A "$BEFORE" "$GITHUB_SHA" -- release-notes/ \
53
+ | sed -n 's#^release-notes/\(.*\)\.md$#\1#p' | sort -V | tr '\n' ' ')
54
+ fi
55
+ echo "list=$versions" >> "$GITHUB_OUTPUT"
56
+ echo "versions: ${versions:-none}"
57
+
58
+ - name: Post the notes
59
+ if: steps.versions.outputs.list != ''
60
+ env:
61
+ DISCORD_WEBHOOK_URL: ${{ secrets.DISCORD_RELEASES_WEBHOOK }}
62
+ VERSIONS: ${{ steps.versions.outputs.list }}
63
+ run: |
64
+ if [ -z "$DISCORD_WEBHOOK_URL" ]; then
65
+ echo "::warning::DISCORD_RELEASES_WEBHOOK is not set, nothing posted"
66
+ exit 0
67
+ fi
68
+ for v in $VERSIONS; do
69
+ python hooks/announce.py "$v"
70
+ done
@@ -0,0 +1,3 @@
1
+ {
2
+ ".": "0.3.0"
3
+ }
@@ -1,5 +1,12 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.3.0](https://github.com/ispx-limited/bbfmodels/compare/v0.2.1...v0.3.0) (2026-11-02)
4
+
5
+
6
+ ### Added
7
+
8
+ * **paths:** typed paths with autocomplete for every model, no pydantic model needed ([#17](https://github.com/ispx-limited/bbfmodels/issues/17)) ([ba3a7b7](https://github.com/ispx-limited/bbfmodels/commit/ba3a7b7781129477aed7ee015d51f9079521b331))
9
+
3
10
  ## [0.2.1](https://github.com/ispx-limited/bbfmodels/compare/v0.2.0...v0.2.1) (2026-11-02)
4
11
 
5
12
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: bbfmodels
3
- Version: 0.2.1
3
+ Version: 0.3.0
4
4
  Summary: Typed models and schema tooling for Broadband Forum data models (TR-181, TR-098, TR-104 and more), generated from the published XML
5
5
  Project-URL: Homepage, https://github.com/ispx-limited/bbfmodels
6
6
  Project-URL: Documentation, https://docs.bbfmodels.ispx.co/
@@ -43,7 +43,10 @@ the same parameter paths as strings. bbfmodels does it once:
43
43
  - Generated typed bindings: pydantic models for Python, shipped for TR-181
44
44
  and TR-098 and the service models (TR-104 voice, TR-135 set-top box,
45
45
  TR-140 storage, TR-196 femtocell, TR-517 Matter), and generated on demand
46
- for any other document, a vendor's included. JSON Schema and TypeScript follow from the
46
+ for any other document, a vendor's included.
47
+ - Typed paths for code that only needs correct path strings:
48
+ `str(Device.WiFi.SSID[1].SSID)` with autocomplete over the whole model
49
+ and the parameter's definition one attribute away. JSON Schema and TypeScript follow from the
47
50
  same representation, Go when there is a consumer.
48
51
 
49
52
  Names stay as the Forum wrote them. `Device.WiFi.SSID.{i}.SSID` is a table of
@@ -18,7 +18,10 @@ the same parameter paths as strings. bbfmodels does it once:
18
18
  - Generated typed bindings: pydantic models for Python, shipped for TR-181
19
19
  and TR-098 and the service models (TR-104 voice, TR-135 set-top box,
20
20
  TR-140 storage, TR-196 femtocell, TR-517 Matter), and generated on demand
21
- for any other document, a vendor's included. JSON Schema and TypeScript follow from the
21
+ for any other document, a vendor's included.
22
+ - Typed paths for code that only needs correct path strings:
23
+ `str(Device.WiFi.SSID[1].SSID)` with autocomplete over the whole model
24
+ and the parameter's definition one attribute away. JSON Schema and TypeScript follow from the
22
25
  same representation, Go when there is a consumer.
23
26
 
24
27
  Names stay as the Forum wrote them. `Device.WiFi.SSID.{i}.SSID` is a table of
@@ -21,3 +21,4 @@ changes, a new record is written and the old one is marked superseded.
21
21
  | [0008](decisions/0008-python-toolchain.md) | Python toolchain: uv, ruff, mypy, pytest, standard library XML | Accepted |
22
22
  | [0009](decisions/0009-the-tree-keeps-wire-text.md) | The data tree keeps wire text and decodes on demand | Accepted |
23
23
  | [0010](decisions/0010-generated-python-packages.md) | One generated package per document, lenient on input, strict in `problems` | Accepted |
24
+ | [0011](decisions/0011-typed-paths-are-a-stub-over-the-schema.md) | Typed paths are a generic runtime plus a stub, not generated classes | Accepted |
@@ -0,0 +1,44 @@
1
+ # 0011: Typed paths are a generic runtime plus a stub, not generated classes
2
+
3
+ ## Context
4
+
5
+ Not every user wants models. Code that queries an ACS API asks for a
6
+ parameter by its path string and gets a string back, and what it needs
7
+ from bbfmodels is a correct path with autocomplete and the parameter's
8
+ definition one step away. Generating a class per object with a property
9
+ per member would give that, at the cost of another megabyte of code per
10
+ package, import time to match, and a second copy of every name the models
11
+ already carry.
12
+
13
+ ## Decision
14
+
15
+ Typed paths are one generic runtime (`bbfmodels.paths`) that walks the
16
+ package's shipped IR, plus a generated stub file (`paths.pyi`) per package
17
+ that declares every object and parameter with the Python type of its
18
+ value. The runtime `paths.py` in a package is three lines: the root path
19
+ over the package's schema. Editors and type checkers read the stub; the
20
+ interpreter never does.
21
+
22
+ - `str()` of a path is the data path. A table renders as its partial path
23
+ and offers `search` for the USP wildcard form and `schema_path` for the
24
+ `{i}` form. Paths compare and hash as strings.
25
+ - `definition` returns the IR object or parameter.
26
+ - An unknown name is an `AttributeError`. A name the schema does not list
27
+ is reached with `child()`, so a typo in a standard name is never taken
28
+ for a vendor parameter.
29
+ - Identifiers follow the models' rule (`N11kEnable` for `11kEnable`), and
30
+ the runtime maps the identifier back to the Forum name.
31
+
32
+ pydantic remains a dependency even for a user who only wants paths, because
33
+ the IR the runtime walks is built on it. That is accepted: the cost is one
34
+ ubiquitous package, and a second dependency-free distribution can be split
35
+ out if someone needs it.
36
+
37
+ ## Consequences
38
+
39
+ - Autocomplete over the whole of TR-181 with no import cost: the stub for
40
+ TR-181 is a few hundred kilobytes that only tools read.
41
+ - The first attribute access loads the package's IR (about 50 ms); every
42
+ one after that is a dictionary lookup.
43
+ - The value type in the stub (`ParamPath[int]`) is documentation for the
44
+ reader and the type checker; the runtime does not use it.
@@ -0,0 +1,86 @@
1
+ # Typed paths
2
+
3
+ Most code that talks to an ACS or a USP controller never builds a tree of
4
+ values. It asks an API for `Device.WiFi.SSID.1.SSID` by name and reads a
5
+ string back. Typed paths make that name a chain of attributes an editor
6
+ completes and a type checker verifies, with no model involved:
7
+
8
+ ```python
9
+ from bbfmodels.tr181_cwmp.paths import Device
10
+
11
+ str(Device.WiFi.SSID[1].SSID) # 'Device.WiFi.SSID.1.SSID'
12
+ str(Device.IP.Interface[1].IPv4Address[2].IPAddress)
13
+ Device.WiFi.Radio[2].Channel == "Device.WiFi.Radio.2.Channel" # True
14
+ ```
15
+
16
+ Every shipped package has a `paths` module whose root is the model's root
17
+ object. A table is indexed by instance number; the table itself renders as
18
+ the partial path CWMP uses to ask for all of it, and `search` gives the USP
19
+ search path:
20
+
21
+ ```python
22
+ str(Device.WiFi.Radio) # 'Device.WiFi.Radio.'
23
+ Device.WiFi.Radio.search # 'Device.WiFi.Radio.*.'
24
+ Device.WiFi.Radio.schema_path # 'Device.WiFi.Radio.{i}.'
25
+ ```
26
+
27
+ A path knows its definition in the shipped schema, so the type, access,
28
+ constraints and description of a parameter are one attribute away:
29
+
30
+ ```python
31
+ channel = Device.WiFi.Radio[1].Channel
32
+ channel.definition.syntax.base_type # <BaseType.UNSIGNED_INT: 'unsignedInt'>
33
+ channel.definition.access # <Access.READ_WRITE: 'readWrite'>
34
+ channel.definition.syntax.facets.ranges # (Range(min_inclusive=1, max_inclusive=255, step=None),)
35
+ channel.definition.description[:60]
36
+ Device.WiFi.Radio.definition.num_entries_parameter # 'RadioNumberOfEntries'
37
+ ```
38
+
39
+ Paths compare and hash as their string, so they work as dictionary keys
40
+ and in sets alongside plain strings.
41
+
42
+ ## Editors and type checkers
43
+
44
+ At runtime one generic class walks the schema, so the `paths` module is
45
+ three lines and costs nothing to import. Beside it, `paths.pyi` is a stub
46
+ that declares every object and parameter with the Python type of its
47
+ value, which is what the editor completes and the type checker reads:
48
+
49
+ ```python
50
+ class WiFi_RadioPath(ObjectPathBase):
51
+ Enable: ParamPath[bool]
52
+ Channel: ParamPath[int]
53
+ SupportedFrequencyBands: ParamPath[list[str]]
54
+ Stats: WiFi_Radio_StatsPath
55
+ ```
56
+
57
+ A typo is caught twice: the type checker rejects `Device.WiFi.Radioo`, and
58
+ at runtime it raises `AttributeError` naming the object that has no such
59
+ member.
60
+
61
+ ## Names the schema does not know
62
+
63
+ A vendor parameter whose document was not generated is reached
64
+ explicitly, so a typo in a standard name is never silently taken for one:
65
+
66
+ ```python
67
+ str(Device.WiFi.Radio[1].child("X_ACME_TxPower")) # 'Device.WiFi.Radio.1.X_ACME_TxPower'
68
+ ```
69
+
70
+ Generate the vendor's document instead and the name completes like any
71
+ other; see [vendor models](vendor-models.md). A Forum name that is not a
72
+ Python identifier is exposed the way the models expose it, `N11kEnable` for
73
+ `11kEnable`, and renders the Forum's spelling.
74
+
75
+ ## Service models
76
+
77
+ A service model's root is a table, and the document does not say where a
78
+ device mounts it, so its paths render from the document's root. Prefix the
79
+ mount when calling an API:
80
+
81
+ ```python
82
+ from bbfmodels.tr104_cwmp.paths import VoiceService
83
+
84
+ str(VoiceService[1].Capabilities.MaxLineCount) # 'VoiceService.1.Capabilities.MaxLineCount'
85
+ "Device.Services." + str(VoiceService[1].Capabilities.MaxLineCount)
86
+ ```
@@ -31,6 +31,18 @@ device.flatten() # back to path and text pairs
31
31
  The [models guide](models.md) covers construction, validation, tables,
32
32
  vendor parameters and the service models.
33
33
 
34
+ ## Correct paths with autocomplete, no models
35
+
36
+ ```python
37
+ from bbfmodels.tr181_cwmp.paths import Device
38
+
39
+ str(Device.WiFi.SSID[1].SSID) # 'Device.WiFi.SSID.1.SSID'
40
+ Device.WiFi.Radio[1].Channel.definition.access # <Access.READ_WRITE: 'readWrite'>
41
+ ```
42
+
43
+ The [typed paths guide](paths.md) covers tables, search paths and vendor
44
+ names.
45
+
34
46
  ## Resolve and validate paths without generated code
35
47
 
36
48
  ```python
@@ -40,8 +40,8 @@ Resolve a path, validate a value against the model's constraints, and convert be
40
40
  </div>
41
41
 
42
42
  <div class="ispx-card" markdown>
43
- ### Typed models
44
- pydantic models for TR-181, TR-098 and every service model, and a generator for any vendor's document. Names stay as the Forum wrote them.
43
+ ### Typed models and paths
44
+ pydantic models for TR-181, TR-098 and every service model, typed paths with autocomplete for code that only needs the string, and a generator for any vendor's document.
45
45
  </div>
46
46
 
47
47
  </div>
@@ -0,0 +1,102 @@
1
+ """Post one release's notes to a Discord channel.
2
+
3
+ The notes the docs site renders for a version (release-notes/<version>.md,
4
+ see changelog.py) are also the text a reader of the ispx Discord gets when
5
+ the release lands: one message per release, the version as the title linked
6
+ to the version's section of the Changelog page, the notes as the body. The
7
+ webhook URL arrives in DISCORD_WEBHOOK_URL and is never printed. A version
8
+ whose notes are longer than a Discord embed allows (4096 characters) has its
9
+ body cut at the last whole line that fits; the notes standard keeps them far
10
+ shorter, so the cut is a guard, not a path.
11
+
12
+ Run with: python hooks/announce.py <version>
13
+ """
14
+
15
+ import json
16
+ import os
17
+ import re
18
+ import sys
19
+ import urllib.request
20
+ from pathlib import Path
21
+
22
+ CHANGELOG_URL = "https://docs.bbfmodels.ispx.co/changelog/"
23
+ NOTES_DIR = "release-notes"
24
+ EMBED_DESCRIPTION_LIMIT = 4096
25
+
26
+
27
+ def anchor(changelog, version):
28
+ """The Changelog page's fragment for a version, derived the way mkdocs does.
29
+
30
+ The page heading is the generated "## [1.2.0](compare) (2026-10-29)" with
31
+ its link removed, so its slug is the version and the date with every
32
+ character outside letters, digits, spaces and hyphens dropped. A version
33
+ CHANGELOG.md does not list yet has no section to point at, so the link
34
+ goes to the page itself.
35
+ """
36
+ heading = re.search(
37
+ rf"^## \[?{re.escape(version)}\]?(?:\([^)]*\))? \((\d{{4}}-\d{{2}}-\d{{2}})\)",
38
+ changelog,
39
+ re.M,
40
+ )
41
+ if not heading:
42
+ return ""
43
+ slug = re.sub(r"[^\w\s-]", "", f"{version} ({heading.group(1)})").strip().lower()
44
+ return "#" + re.sub(r"\s+", "-", slug)
45
+
46
+
47
+ def body(notes, limit=EMBED_DESCRIPTION_LIMIT):
48
+ text = notes.strip()
49
+ if len(text) <= limit:
50
+ return text
51
+ cut = text.rfind("\n", 0, limit)
52
+ return text[: cut if cut > 0 else limit].rstrip()
53
+
54
+
55
+ def payload(version, notes, changelog):
56
+ return {
57
+ "username": "bbfmodels releases",
58
+ "allowed_mentions": {"parse": []},
59
+ "embeds": [
60
+ {
61
+ "title": f"bbfmodels {version}",
62
+ "url": CHANGELOG_URL + anchor(changelog, version),
63
+ "description": body(notes),
64
+ }
65
+ ],
66
+ }
67
+
68
+
69
+ def post(url, message):
70
+ request = urllib.request.Request(
71
+ url,
72
+ data=json.dumps(message).encode("utf-8"),
73
+ headers={"Content-Type": "application/json", "User-Agent": "bbfmodels-release-notes"},
74
+ method="POST",
75
+ )
76
+ with urllib.request.urlopen(request, timeout=30) as response:
77
+ return response.status
78
+
79
+
80
+ def main(argv):
81
+ if len(argv) != 2:
82
+ print("usage: announce.py <version>", file=sys.stderr)
83
+ return 2
84
+ version = argv[1]
85
+ url = os.environ.get("DISCORD_WEBHOOK_URL", "")
86
+ if not url:
87
+ print("DISCORD_WEBHOOK_URL is not set, nothing posted", file=sys.stderr)
88
+ return 2
89
+ root = Path(__file__).resolve().parent.parent
90
+ notes = root / NOTES_DIR / f"{version}.md"
91
+ if not notes.is_file():
92
+ print(f"no notes at {NOTES_DIR}/{version}.md", file=sys.stderr)
93
+ return 1
94
+ changelog = (root / "CHANGELOG.md").read_text(encoding="utf-8")
95
+ message = payload(version, notes.read_text(encoding="utf-8"), changelog)
96
+ status = post(url, message)
97
+ print(f"posted {version} ({status})")
98
+ return 0
99
+
100
+
101
+ if __name__ == "__main__":
102
+ sys.exit(main(sys.argv))
@@ -0,0 +1,89 @@
1
+ """Run with: python -m unittest discover -s hooks"""
2
+
3
+ import json
4
+ import threading
5
+ import unittest
6
+ from http.server import BaseHTTPRequestHandler, HTTPServer
7
+
8
+ import announce
9
+
10
+ CHANGELOG = """# Changelog
11
+
12
+ ## [0.76.0](https://example.test/compare/v0.75.2...v0.76.0) (2026-10-29)
13
+
14
+ ### Added
15
+
16
+ * **scripts:** the System page shows what each script costs
17
+
18
+ ## 0.1.0 (2026-08-20)
19
+ """
20
+
21
+ NOTES = """- The System page ranks scripts by run time, host time and failure rate
22
+ - Action: previewing a topology rule now requires the config:write scope
23
+ """
24
+
25
+
26
+ class Anchor(unittest.TestCase):
27
+ def test_matches_the_docs_page_heading_id(self):
28
+ self.assertEqual(announce.anchor(CHANGELOG, "0.76.0"), "#0760-2026-10-29")
29
+
30
+ def test_first_release_heading_has_no_link(self):
31
+ self.assertEqual(announce.anchor(CHANGELOG, "0.1.0"), "#010-2026-08-20")
32
+
33
+ def test_unlisted_version_links_to_the_page(self):
34
+ self.assertEqual(announce.anchor(CHANGELOG, "0.77.0"), "")
35
+ self.assertEqual(
36
+ announce.payload("0.77.0", NOTES, CHANGELOG)["embeds"][0]["url"],
37
+ announce.CHANGELOG_URL,
38
+ )
39
+
40
+
41
+ class Payload(unittest.TestCase):
42
+ def test_one_embed_titled_by_version_linking_to_its_section(self):
43
+ message = announce.payload("0.76.0", NOTES, CHANGELOG)
44
+ self.assertEqual(message["allowed_mentions"], {"parse": []})
45
+ (embed,) = message["embeds"]
46
+ self.assertEqual(embed["title"], "bbfmodels 0.76.0")
47
+ self.assertEqual(embed["url"], announce.CHANGELOG_URL + "#0760-2026-10-29")
48
+ self.assertEqual(embed["description"], NOTES.strip())
49
+
50
+ def test_overlong_notes_are_cut_at_a_whole_line(self):
51
+ lines = "\n".join(f"- line {i} " + "x" * 100 for i in range(60))
52
+ text = announce.body(lines)
53
+ self.assertLessEqual(len(text), announce.EMBED_DESCRIPTION_LIMIT)
54
+ self.assertTrue(text.endswith("x"))
55
+ self.assertEqual(text, lines[: len(text)])
56
+ self.assertEqual(lines[len(text)], "\n")
57
+
58
+
59
+ class Post(unittest.TestCase):
60
+ def test_posts_json_to_the_webhook(self):
61
+ received = {}
62
+
63
+ class Handler(BaseHTTPRequestHandler):
64
+ def do_POST(self):
65
+ length = int(self.headers["Content-Length"])
66
+ received["body"] = json.loads(self.rfile.read(length))
67
+ received["type"] = self.headers["Content-Type"]
68
+ self.send_response(204)
69
+ self.end_headers()
70
+
71
+ def log_message(self, *_):
72
+ pass
73
+
74
+ server = HTTPServer(("127.0.0.1", 0), Handler)
75
+ thread = threading.Thread(target=server.serve_forever, daemon=True)
76
+ thread.start()
77
+ try:
78
+ url = f"http://127.0.0.1:{server.server_port}/webhook"
79
+ status = announce.post(url, announce.payload("0.76.0", NOTES, CHANGELOG))
80
+ finally:
81
+ server.shutdown()
82
+ server.server_close()
83
+ self.assertEqual(status, 204)
84
+ self.assertEqual(received["type"], "application/json")
85
+ self.assertEqual(received["body"]["embeds"][0]["title"], "bbfmodels 0.76.0")
86
+
87
+
88
+ if __name__ == "__main__":
89
+ unittest.main()
@@ -51,6 +51,7 @@ nav:
51
51
  - Documents and the IR: guides/documents.md
52
52
  - Schema, tree and codec: guides/runtime.md
53
53
  - Generated models: guides/models.md
54
+ - Typed paths: guides/paths.md
54
55
  - Vendor models: guides/vendor-models.md
55
56
  - Command line: guides/cli.md
56
57
  - Changelog: changelog.md
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "bbfmodels"
3
- version = "0.2.1"
3
+ version = "0.3.0"
4
4
  description = "Typed models and schema tooling for Broadband Forum data models (TR-181, TR-098, TR-104 and more), generated from the published XML"
5
5
  readme = "README.md"
6
6
  license = "Apache-2.0"
@@ -0,0 +1,4 @@
1
+ - Typed paths: `str(Device.WiFi.SSID[1].SSID)` renders the path, with autocomplete over the whole model
2
+ - A path knows its definition: type, access, constraints and description one attribute away
3
+ - A table renders as its partial path, and `search` gives the USP wildcard form
4
+ - Type checkers reject a misspelled object or parameter name and suggest the right one
@@ -11,6 +11,6 @@ from importlib.metadata import PackageNotFoundError, version
11
11
  try:
12
12
  __version__ = version("bbfmodels")
13
13
  except PackageNotFoundError: # running from a source tree that is not installed
14
- __version__ = "0.2.1"
14
+ __version__ = "0.3.0"
15
15
 
16
16
  __all__ = ["__version__"]
@@ -17,12 +17,12 @@ from __future__ import annotations
17
17
 
18
18
  import gzip
19
19
  import keyword
20
- import re
21
20
  from pathlib import Path
22
21
 
23
22
  from pydantic import BaseModel
24
23
 
25
24
  from bbfmodels.ir import BaseType, Document, Model, Object, Parameter
25
+ from bbfmodels.paths import identifier
26
26
 
27
27
  # The documents the shipped packages are generated from. A package is named
28
28
  # after its document: the protocol suffix appears where the Forum publishes
@@ -110,19 +110,26 @@ def generate(doc: Document, package: str, out: Path) -> list[Path]:
110
110
  root_path.write_text(body)
111
111
  written.append(root_path)
112
112
 
113
+ paths_py = out / "paths.py"
114
+ paths_py.write_text(_emit_paths_module(model, root, package, source))
115
+ written.append(paths_py)
116
+ paths_pyi = out / "paths.pyi"
117
+ paths_pyi.write_text(_emit_paths_stub(model, root, source))
118
+ written.append(paths_pyi)
119
+
113
120
  init = (
114
121
  f'"""{model.name} from {source}.\n\n'
115
122
  f"Generated by bbfmodels. Do not edit: change the generator or the source\n"
116
123
  f"document and regenerate. ``schema()`` loads the IR the models were\n"
117
124
  f'generated from, for validation and descriptions.\n"""\n\n'
118
125
  f"from bbfmodels.model import load_schema\n"
119
- f"from {package}.{modules['']} import {root}\n\n"
126
+ f"from {package}.{modules['']} import {identifier(root)}\n\n"
120
127
  f'SOURCE = "{source}"\n'
121
128
  f'SPEC = "{doc.spec}"\n'
122
129
  f'MODEL = "{model.name}"\n\n\n'
123
130
  f"def schema(): # type: ignore[no-untyped-def]\n"
124
131
  f" return load_schema(__name__)\n\n\n"
125
- f'__all__ = ["{root}", "MODEL", "SOURCE", "SPEC", "schema"]\n'
132
+ f'__all__ = ["{identifier(root)}", "MODEL", "SOURCE", "SPEC", "schema"]\n'
126
133
  )
127
134
  init_path = out / "__init__.py"
128
135
  init_path.write_text(init)
@@ -176,20 +183,6 @@ def _postorder(objects: list[Object]) -> list[Object]:
176
183
  return sorted(objects, key=lambda o: -o.path.count("."))
177
184
 
178
185
 
179
- def identifier(name: str) -> str:
180
- """A Forum name as a Python identifier.
181
-
182
- Forum names are identifiers already except in vendor documents, where a
183
- name may start with a digit (``11kRSSIHighThresholdOffset``) or carry a
184
- hyphen. A leading digit gets an ``N`` in front, because a leading
185
- underscore would make pydantic treat the field as private, and any other
186
- character Python rejects becomes an underscore. The wire name is kept
187
- as the field's alias, so conversion is unaffected.
188
- """
189
- out = re.sub(r"\W", "_", name)
190
- return "N" + out if out[:1].isdigit() else out
191
-
192
-
193
186
  def class_name(obj: Object, root: str) -> str:
194
187
  segments = [s for s in obj.path.rstrip(".").split(".") if s != "{i}"]
195
188
  return identifier(root) if len(segments) == 1 else identifier("_".join(segments[1:]))
@@ -269,3 +262,68 @@ def write_package(package: str, document: Path, root: Path) -> list[Path]:
269
262
 
270
263
  out = root.joinpath(*package.split("."))
271
264
  return generate(parse_file(document), package, out)
265
+
266
+
267
+ _STUB_TYPE = {
268
+ BaseType.STRING: "str",
269
+ BaseType.INT: "int",
270
+ BaseType.UNSIGNED_INT: "int",
271
+ BaseType.LONG: "int",
272
+ BaseType.UNSIGNED_LONG: "int",
273
+ BaseType.BOOLEAN: "bool",
274
+ BaseType.DATE_TIME: "datetime",
275
+ BaseType.HEX_BINARY: "bytes",
276
+ BaseType.BASE64: "bytes",
277
+ BaseType.DECIMAL: "Decimal",
278
+ }
279
+
280
+
281
+ def _emit_paths_module(model: Model, root: str, package: str, source: str) -> str:
282
+ """The runtime half of typed paths: one root object over the package's schema."""
283
+ root_obj = next(iter(model.objects.values()))
284
+ kind = "TablePath" if root_obj.multi_instance else "ObjectPath"
285
+ data = root_obj.path.replace("{i}.", "")
286
+ return (
287
+ _HEADER.format(source=source)
288
+ + "from bbfmodels.model import load_schema as _load_schema\n"
289
+ + f"from bbfmodels.paths import {kind} as _{kind}\n\n\n"
290
+ + "def _schema(): # type: ignore[no-untyped-def]\n"
291
+ + f' return _load_schema("{package}")\n\n\n'
292
+ + f'{identifier(root)} = _{kind}(_schema, "{data}", "{root_obj.path}")\n'
293
+ )
294
+
295
+
296
+ def _emit_paths_stub(model: Model, root: str, source: str) -> str:
297
+ """The stub editors read: a class per object with every name and value type."""
298
+ lines = [
299
+ _HEADER.format(source=source),
300
+ "from datetime import datetime\n",
301
+ "from decimal import Decimal\n",
302
+ "from bbfmodels.paths import ObjectPathBase, ParamPath, TablePath\n\n",
303
+ ]
304
+ for obj in _postorder(list(model.objects.values())):
305
+ name = class_name(obj, root) + "Path"
306
+ lines.append(f"class {name}(ObjectPathBase):\n")
307
+ for param in obj.parameters.values():
308
+ s = param.syntax
309
+ value = _STUB_TYPE[s.base_type]
310
+ if s.list is not None:
311
+ value = f"list[{value}]"
312
+ lines.append(f" {identifier(param.name)}: ParamPath[{value}]\n")
313
+ for child in _children(obj, model):
314
+ child_name = class_name(child, root) + "Path"
315
+ field = identifier(child.name)
316
+ if child.multi_instance:
317
+ lines.append(f" {field}: TablePath[{child_name}]\n")
318
+ else:
319
+ lines.append(f" {field}: {child_name}\n")
320
+ if not obj.parameters and not _children(obj, model):
321
+ lines.append(" pass\n")
322
+ lines.append("\n")
323
+ root_obj = next(iter(model.objects.values()))
324
+ root_name = class_name(root_obj, root) + "Path"
325
+ if root_obj.multi_instance:
326
+ lines.append(f"{identifier(root)}: TablePath[{root_name}]\n")
327
+ else:
328
+ lines.append(f"{identifier(root)}: {root_name}\n")
329
+ return "".join(lines)