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.
- bbfmodels-0.3.0/.github/workflows/announce-release.yml +70 -0
- bbfmodels-0.3.0/.release-please-manifest.json +3 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/CHANGELOG.md +7 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/PKG-INFO +5 -2
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/README.md +4 -1
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/context/README.md +1 -0
- bbfmodels-0.3.0/context/decisions/0011-typed-paths-are-a-stub-over-the-schema.md +44 -0
- bbfmodels-0.3.0/docs/guides/paths.md +86 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/docs/guides/quickstart.md +12 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/docs/index.md +2 -2
- bbfmodels-0.3.0/hooks/announce.py +102 -0
- bbfmodels-0.3.0/hooks/test_announce.py +89 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/mkdocs.yml +1 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/pyproject.toml +1 -1
- bbfmodels-0.3.0/release-notes/0.3.0.md +4 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/__init__.py +1 -1
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/generate.py +75 -17
- bbfmodels-0.3.0/src/bbfmodels/paths.py +154 -0
- bbfmodels-0.3.0/src/bbfmodels/tr098/paths.py +13 -0
- bbfmodels-0.3.0/src/bbfmodels/tr098/paths.pyi +2387 -0
- bbfmodels-0.3.0/src/bbfmodels/tr104_1/paths.py +13 -0
- bbfmodels-0.3.0/src/bbfmodels/tr104_1/paths.pyi +486 -0
- bbfmodels-0.3.0/src/bbfmodels/tr104_cwmp/paths.py +13 -0
- bbfmodels-0.3.0/src/bbfmodels/tr104_cwmp/paths.pyi +1195 -0
- bbfmodels-0.3.0/src/bbfmodels/tr104_usp/paths.py +13 -0
- bbfmodels-0.3.0/src/bbfmodels/tr104_usp/paths.pyi +1177 -0
- bbfmodels-0.3.0/src/bbfmodels/tr135_cwmp/paths.py +13 -0
- bbfmodels-0.3.0/src/bbfmodels/tr135_cwmp/paths.pyi +823 -0
- bbfmodels-0.3.0/src/bbfmodels/tr135_usp/paths.py +13 -0
- bbfmodels-0.3.0/src/bbfmodels/tr135_usp/paths.pyi +795 -0
- bbfmodels-0.3.0/src/bbfmodels/tr140_cwmp/paths.py +13 -0
- bbfmodels-0.3.0/src/bbfmodels/tr140_cwmp/paths.pyi +190 -0
- bbfmodels-0.3.0/src/bbfmodels/tr140_usp/paths.py +13 -0
- bbfmodels-0.3.0/src/bbfmodels/tr140_usp/paths.pyi +190 -0
- bbfmodels-0.3.0/src/bbfmodels/tr181_cwmp/paths.py +13 -0
- bbfmodels-0.3.0/src/bbfmodels/tr181_cwmp/paths.pyi +11041 -0
- bbfmodels-0.3.0/src/bbfmodels/tr181_usp/paths.py +13 -0
- bbfmodels-0.3.0/src/bbfmodels/tr181_usp/paths.pyi +10344 -0
- bbfmodels-0.3.0/src/bbfmodels/tr196_cwmp/paths.py +13 -0
- bbfmodels-0.3.0/src/bbfmodels/tr196_cwmp/paths.pyi +2476 -0
- bbfmodels-0.3.0/src/bbfmodels/tr196_usp/paths.py +13 -0
- bbfmodels-0.3.0/src/bbfmodels/tr196_usp/paths.pyi +2476 -0
- bbfmodels-0.3.0/src/bbfmodels/tr517_usp/paths.py +13 -0
- bbfmodels-0.3.0/src/bbfmodels/tr517_usp/paths.pyi +6314 -0
- bbfmodels-0.3.0/tests/test_paths.py +95 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/uv.lock +1 -1
- bbfmodels-0.2.1/.release-please-manifest.json +0 -3
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/.github/workflows/ci.yml +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/.github/workflows/docs.yml +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/.github/workflows/pr-title.yml +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/.github/workflows/publish.yml +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/.github/workflows/release-please.yml +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/.gitignore +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/.python-version +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/CLAUDE.md +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/CONTRIBUTING.md +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/LICENSE +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/Makefile +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/NOTICE +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/context/decisions/0001-one-parser-one-ir-several-emitters.md +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/context/decisions/0002-names-stay-as-the-forum-wrote-them.md +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/context/decisions/0003-parse-the-flattened-full-documents.md +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/context/decisions/0004-generated-output-is-committed.md +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/context/decisions/0005-python-models-are-pydantic.md +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/context/decisions/0006-everything-optional-unknown-paths-kept.md +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/context/decisions/0007-vendor-extensions-are-overlays.md +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/context/decisions/0008-python-toolchain.md +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/context/decisions/0009-the-tree-keeps-wire-text.md +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/context/decisions/0010-generated-python-packages.md +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/docs/assets/images/ispx-icon.png +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/docs/assets/js/copy-code.js +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/docs/assets/js/powered-by.js +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/docs/assets/stylesheets/extra.css +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/docs/changelog.md +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/docs/guides/cli.md +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/docs/guides/documents.md +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/docs/guides/models.md +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/docs/guides/runtime.md +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/docs/guides/vendor-models.md +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/hooks/changelog.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/hooks/test_changelog.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/release-notes/0.1.0.md +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/release-notes/0.2.0.md +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/release-notes/0.2.1.md +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/release-please-config.json +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/requirements.txt +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/scripts/bootstrap.sh +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/cli.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/codec.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/ir.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/model.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/parser.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/py.typed +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/schema.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/sources.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr098/__init__.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr098/bulkdata.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr098/capabilities.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr098/captiveportal.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr098/deviceconfig.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr098/deviceinfo.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr098/dlna.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr098/dns.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr098/downloadavailability.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr098/downloaddiagnostics.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr098/fap.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr098/faultmgmt.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr098/firewall.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr098/internetgatewaydevice.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr098/ippingdiagnostics.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr098/ir.json.gz +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr098/lanconfigsecurity.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr098/landevice.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr098/laninterfaces.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr098/layer2bridging.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr098/layer3forwarding.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr098/managementserver.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr098/nslookupdiagnostics.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr098/periodicstatistics.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr098/queuemanagement.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr098/security.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr098/selftestdiagnostics.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr098/services.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr098/smartcardreader.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr098/softwaremodules.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr098/time.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr098/traceroutediagnostics.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr098/udpechoconfig.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr098/uploaddiagnostics.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr098/upnp.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr098/usbhosts.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr098/user.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr098/userinterface.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr098/wandevice.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr098/xmpp.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr104_1/__init__.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr104_1/capabilities.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr104_1/ir.json.gz +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr104_1/phyinterface.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr104_1/voiceprofile.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr104_1/voiceservice.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr104_cwmp/__init__.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr104_cwmp/callcontrol.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr104_cwmp/calllog.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr104_cwmp/capabilities.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr104_cwmp/clocksynchronization.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr104_cwmp/codecprofile.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr104_cwmp/dect.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr104_cwmp/h323.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr104_cwmp/interwork.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr104_cwmp/ir.json.gz +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr104_cwmp/isdn.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr104_cwmp/mgcp.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr104_cwmp/pots.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr104_cwmp/reservedports.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr104_cwmp/sip.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr104_cwmp/terminal.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr104_cwmp/tone.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr104_cwmp/trunk.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr104_cwmp/voiceservice.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr104_cwmp/voipprofile.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr104_usp/__init__.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr104_usp/callcontrol.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr104_usp/calllog.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr104_usp/capabilities.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr104_usp/clocksynchronization.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr104_usp/codecprofile.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr104_usp/dect.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr104_usp/h323.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr104_usp/interwork.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr104_usp/ir.json.gz +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr104_usp/isdn.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr104_usp/mgcp.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr104_usp/pots.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr104_usp/reservedports.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr104_usp/sip.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr104_usp/terminal.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr104_usp/tone.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr104_usp/trunk.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr104_usp/voiceservice.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr104_usp/voipprofile.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr135_cwmp/__init__.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr135_cwmp/applications.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr135_cwmp/avplayers.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr135_cwmp/avstreams.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr135_cwmp/capabilities.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr135_cwmp/components.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr135_cwmp/ir.json.gz +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr135_cwmp/servicemonitoring.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr135_cwmp/stbservice.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr135_usp/__init__.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr135_usp/applications.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr135_usp/avplayers.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr135_usp/avstreams.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr135_usp/capabilities.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr135_usp/components.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr135_usp/ir.json.gz +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr135_usp/servicemonitoring.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr135_usp/stbservice.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr140_cwmp/__init__.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr140_cwmp/capabilities.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr140_cwmp/ftpserver.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr140_cwmp/httpserver.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr140_cwmp/httpsserver.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr140_cwmp/ir.json.gz +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr140_cwmp/logicalvolume.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr140_cwmp/netinfo.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr140_cwmp/networkserver.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr140_cwmp/physicalmedium.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr140_cwmp/sftpserver.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr140_cwmp/storagearray.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr140_cwmp/storageservice.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr140_cwmp/useraccount.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr140_cwmp/usergroup.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr140_usp/__init__.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr140_usp/capabilities.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr140_usp/ftpserver.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr140_usp/httpserver.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr140_usp/httpsserver.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr140_usp/ir.json.gz +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr140_usp/logicalvolume.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr140_usp/netinfo.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr140_usp/networkserver.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr140_usp/physicalmedium.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr140_usp/sftpserver.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr140_usp/storagearray.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr140_usp/storageservice.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr140_usp/useraccount.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr140_usp/usergroup.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_cwmp/__init__.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_cwmp/atm.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_cwmp/basapm.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_cwmp/bridging.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_cwmp/bulkdata.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_cwmp/captiveportal.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_cwmp/cellular.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_cwmp/collectiondevice.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_cwmp/connectionmonitoring.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_cwmp/device.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_cwmp/deviceinfo.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_cwmp/dhcpv4.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_cwmp/dhcpv6.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_cwmp/dlna.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_cwmp/dns.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_cwmp/docsis.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_cwmp/dsl.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_cwmp/dslite.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_cwmp/dynamicdns.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_cwmp/ethernet.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_cwmp/etsim2m.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_cwmp/fap.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_cwmp/fast.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_cwmp/faultmgmt.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_cwmp/firewall.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_cwmp/fwe.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_cwmp/gatewayinfo.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_cwmp/ghn.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_cwmp/gre.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_cwmp/hardware.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_cwmp/homeplug.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_cwmp/hosts.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_cwmp/hpna.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_cwmp/ieee1905.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_cwmp/ieee8021x.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_cwmp/interfacestack.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_cwmp/ip.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_cwmp/ipsec.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_cwmp/ipv6rd.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_cwmp/ir.json.gz +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_cwmp/l2tpv3.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_cwmp/lanconfigsecurity.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_cwmp/leds.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_cwmp/lldp.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_cwmp/lmap.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_cwmp/logical.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_cwmp/managementserver.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_cwmp/map.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_cwmp/moca.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_cwmp/mqtt.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_cwmp/nat.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_cwmp/neighbordiscovery.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_cwmp/optical.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_cwmp/packetcapturediagnostics.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_cwmp/pcp.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_cwmp/pdu.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_cwmp/periodicfiletransfer.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_cwmp/periodicstatistics.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_cwmp/ppp.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_cwmp/ptm.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_cwmp/qos.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_cwmp/radsecproxy.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_cwmp/routeradvertisement.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_cwmp/routing.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_cwmp/schedules.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_cwmp/security.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_cwmp/selftestdiagnostics.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_cwmp/services.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_cwmp/sessionmanagement.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_cwmp/sfps.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_cwmp/smartcardreaders.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_cwmp/softwaremodules.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_cwmp/ssh.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_cwmp/stomp.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_cwmp/syslog.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_cwmp/thread.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_cwmp/time.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_cwmp/trustedelements.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_cwmp/unixdomainsockets.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_cwmp/upa.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_cwmp/upnp.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_cwmp/usb.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_cwmp/userinterface.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_cwmp/users.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_cwmp/uspagent.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_cwmp/uspservices.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_cwmp/vxlan.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_cwmp/wifi.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_cwmp/wireguard.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_cwmp/wwc.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_cwmp/xmpp.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_cwmp/xpon.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_cwmp/zigbee.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_usp/__init__.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_usp/atm.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_usp/basapm.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_usp/bridging.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_usp/bulkdata.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_usp/captiveportal.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_usp/cellular.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_usp/collectiondevice.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_usp/connectionmonitoring.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_usp/cwmpmanagementserver.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_usp/device.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_usp/deviceinfo.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_usp/dhcpv4.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_usp/dhcpv6.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_usp/dlna.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_usp/dns.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_usp/docsis.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_usp/dsl.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_usp/dslite.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_usp/dynamicdns.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_usp/ethernet.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_usp/fap.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_usp/fast.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_usp/faultmgmt.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_usp/firewall.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_usp/fwe.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_usp/gatewayinfo.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_usp/ghn.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_usp/gre.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_usp/hardware.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_usp/homeplug.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_usp/hosts.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_usp/hpna.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_usp/ieee1905.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_usp/ieee8021x.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_usp/interfacestack.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_usp/iotcapability.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_usp/ip.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_usp/ipsec.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_usp/ipv6rd.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_usp/ir.json.gz +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_usp/l2tpv3.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_usp/lanconfigsecurity.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_usp/leds.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_usp/lldp.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_usp/lmap.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_usp/localagent.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_usp/logical.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_usp/map.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_usp/moca.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_usp/mqtt.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_usp/nat.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_usp/neighbordiscovery.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_usp/node.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_usp/optical.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_usp/pcp.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_usp/pdu.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_usp/periodicfiletransfer.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_usp/periodicstatistics.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_usp/ppp.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_usp/proxieddevice.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_usp/ptm.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_usp/qos.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_usp/radsecproxy.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_usp/routeradvertisement.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_usp/routing.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_usp/schedules.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_usp/security.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_usp/services.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_usp/sessionmanagement.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_usp/sfps.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_usp/smartcardreaders.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_usp/softwaremodules.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_usp/ssh.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_usp/standby.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_usp/stomp.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_usp/syslog.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_usp/thread.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_usp/time.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_usp/trustedelements.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_usp/unixdomainsockets.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_usp/upa.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_usp/upnp.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_usp/usb.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_usp/userinterface.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_usp/users.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_usp/uspservices.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_usp/vxlan.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_usp/wifi.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_usp/wireguard.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_usp/wwc.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_usp/xmpp.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_usp/xpon.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr181_usp/zigbee.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr196_cwmp/__init__.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr196_cwmp/accessmgmt.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr196_cwmp/capabilities.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr196_cwmp/cellconfig.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr196_cwmp/fapcontrol.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr196_cwmp/fapservice.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr196_cwmp/ir.json.gz +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr196_cwmp/rem.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr196_cwmp/transport.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr196_usp/__init__.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr196_usp/accessmgmt.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr196_usp/capabilities.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr196_usp/cellconfig.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr196_usp/fapcontrol.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr196_usp/fapservice.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr196_usp/ir.json.gz +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr196_usp/rem.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr196_usp/transport.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/__init__.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/accesscontrolcluster.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/accountlogincluster.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/actionscluster.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/activatedcarbonfiltermonitoringcluster.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/administratorcommissioningcluster.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/airqualitycluster.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/applicationbasiccluster.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/applicationlaunchercluster.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/audiooutputcluster.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/basicinformationcluster.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/bindingcluster.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/booleanstatecluster.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/booleanstateconfigurationcluster.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/bridgeddevicebasicinformationcluster.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/cameraavsettingsuserlevelmanagementcluster.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/cameraavstreammanagementcluster.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/carbondioxideconcentrationmeasurementcluster.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/carbonmonoxideconcentrationmeasurementcluster.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/channelcluster.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/chimecluster.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/closurecontrolcluster.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/closuredimensioncluster.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/colorcontrolcluster.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/commissionercontrolcluster.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/commoditymeteringcluster.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/commoditypricecluster.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/commoditytariffcluster.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/contentappobservercluster.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/contentcontrolcluster.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/contentlaunchercluster.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/descriptorcluster.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/deviceenergymanagementcluster.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/deviceenergymanagementmodecluster.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/diagnosticlogscluster.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/dishwasheralarmcluster.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/dishwashermodecluster.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/doorlockcluster.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/ecosysteminformationcluster.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/electricalenergymeasurementcluster.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/electricalgridconditionscluster.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/electricalpowermeasurementcluster.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/endpoint.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/energyevsecluster.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/energyevsemodecluster.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/energypreferencecluster.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/ethernetnetworkdiagnosticscluster.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/fabric.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/fancontrolcluster.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/fixedlabelcluster.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/flowmeasurementcluster.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/formaldehydeconcentrationmeasurementcluster.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/generalcommissioningcluster.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/generaldiagnosticscluster.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/groupkeymanagementcluster.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/groupscluster.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/hepafiltermonitoringcluster.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/icdmanagementcluster.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/identifycluster.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/illuminancemeasurementcluster.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/ir.json.gz +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/jointfabricadministratorcluster.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/jointfabricdatastorecluster.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/keypadinputcluster.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/laundrydryercontrolscluster.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/laundrywashercontrolscluster.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/laundrywashermodecluster.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/levelcontrolcluster.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/localizationconfigurationcluster.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/lowpowercluster.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/matterservice.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/mediainputcluster.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/mediaplaybackcluster.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/messagescluster.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/meteridentificationcluster.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/microwaveovencontrolcluster.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/microwaveovenmodecluster.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/modeselectcluster.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/network.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/networkcommissioningcluster.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/nitrogendioxideconcentrationmeasurementcluster.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/occupancysensingcluster.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/onoffcluster.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/operationalcredentialscluster.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/operationalstatecluster.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/otasoftwareupdateprovidercluster.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/otasoftwareupdaterequestorcluster.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/ovencavityoperationalstatecluster.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/ovenmodecluster.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/ozoneconcentrationmeasurementcluster.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/pm10concentrationmeasurementcluster.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/pm1concentrationmeasurementcluster.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/pm25concentrationmeasurementcluster.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/powersourcecluster.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/powersourceconfigurationcluster.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/powertopologycluster.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/pressuremeasurementcluster.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/pumpconfigurationandcontrolcluster.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/pushavstreamtransportcluster.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/radonconcentrationmeasurementcluster.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/refrigeratoralarmcluster.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/refrigeratorandtemperaturecontrolledcabinetmodecluster.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/relativehumiditymeasurementcluster.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/rvccleanmodecluster.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/rvcoperationalstatecluster.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/rvcrunmodecluster.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/scenesmanagementcluster.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/serviceareacluster.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/smokecoalarmcluster.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/softwarediagnosticscluster.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/soilmeasurementcluster.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/switchcluster.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/targetnavigatorcluster.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/temperaturecontrolcluster.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/temperaturemeasurementcluster.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/thermostatcluster.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/thermostatuserinterfaceconfigurationcluster.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/threadborderroutermanagementcluster.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/threadnetworkdiagnosticscluster.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/threadnetworkdirectorycluster.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/timeformatlocalizationcluster.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/timesynchronizationcluster.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/tlscertificatemanagementcluster.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/tlsclientmanagementcluster.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/totalvolatileorganiccompoundsconcentrationmeasurementcluster.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/unitlocalizationcluster.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/userlabelcluster.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/valveconfigurationandcontrolcluster.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/wakeonlancluster.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/waterheatermanagementcluster.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/waterheatermodecluster.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/watertanklevelmonitoringcluster.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/webrtctransportprovidercluster.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/webrtctransportrequestorcluster.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/wifinetworkdiagnosticscluster.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/wifinetworkmanagementcluster.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/windowcoveringcluster.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tr517_usp/zonemanagementcluster.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/src/bbfmodels/tree.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/tests/fixtures/mini-cwmp-full.xml +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/tests/fixtures/mini-service-full.xml +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/tests/fixtures/mini-usp-full.xml +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/tests/test_cli.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/tests/test_codec.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/tests/test_documents.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/tests/test_generate.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/tests/test_parser.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/tests/test_schema.py +0 -0
- {bbfmodels-0.2.1 → bbfmodels-0.3.0}/tests/test_tree.py +0 -0
- {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
|
|
@@ -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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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)
|