{"id":37085727,"url":"https://github.com/research-virtualfortknox/msb-client-websocket-python","last_synced_at":"2026-01-14T10:32:49.333Z","repository":{"id":34925378,"uuid":"190702996","full_name":"research-virtualfortknox/msb-client-websocket-python","owner":"research-virtualfortknox","description":"The python client library to connect to the websocket interface of the MSB (Manufacturing Service Bus) ","archived":false,"fork":false,"pushed_at":"2025-07-22T12:44:02.000Z","size":2284,"stargazers_count":5,"open_issues_count":2,"forks_count":4,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-09-23T00:32:58.122Z","etag":null,"topics":["msb","msb-client","msb-client-websocket","python","websocket-interface"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/research-virtualfortknox.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":".github/CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":".github/CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null}},"created_at":"2019-06-07T07:14:13.000Z","updated_at":"2025-07-22T12:44:06.000Z","dependencies_parsed_at":"2023-10-20T15:16:10.377Z","dependency_job_id":null,"html_url":"https://github.com/research-virtualfortknox/msb-client-websocket-python","commit_stats":{"total_commits":86,"total_committers":8,"mean_commits":10.75,"dds":"0.32558139534883723","last_synced_commit":"c2eff161f70116839f43a178937dbccc71c3c0b4"},"previous_names":[],"tags_count":17,"template":false,"template_full_name":null,"purl":"pkg:github/research-virtualfortknox/msb-client-websocket-python","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/research-virtualfortknox%2Fmsb-client-websocket-python","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/research-virtualfortknox%2Fmsb-client-websocket-python/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/research-virtualfortknox%2Fmsb-client-websocket-python/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/research-virtualfortknox%2Fmsb-client-websocket-python/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/research-virtualfortknox","download_url":"https://codeload.github.com/research-virtualfortknox/msb-client-websocket-python/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/research-virtualfortknox%2Fmsb-client-websocket-python/sbom","scorecard":{"id":771708,"data":{"date":"2025-08-11","repo":{"name":"github.com/research-virtualfortknox/msb-client-websocket-python","commit":"4eb80ae5a081604ca12177447df3d5f6133d2d7b"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":3.5,"checks":[{"name":"Maintained","score":1,"reason":"2 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 1","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Code-Review","score":0,"reason":"Found 0/30 approved changesets -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Dangerous-Workflow","score":10,"reason":"no dangerous workflow patterns detected","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Token-Permissions","score":0,"reason":"detected GitHub workflow tokens with excessive permissions","details":["Warn: no topLevel permission defined: .github/workflows/build.yml:1","Info: no jobLevel write permissions found"],"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"SAST","score":0,"reason":"no SAST tool detected","details":["Warn: no pull requests merged into dev branch"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Pinned-Dependencies","score":0,"reason":"dependency not pinned by hash detected -- score normalized to 0","details":["Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/build.yml:20: update your workflow using https://app.stepsecurity.io/secureworkflow/research-virtualfortknox/msb-client-websocket-python/build.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/build.yml:22: update your workflow using https://app.stepsecurity.io/secureworkflow/research-virtualfortknox/msb-client-websocket-python/build.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/build.yml:50: update your workflow using https://app.stepsecurity.io/secureworkflow/research-virtualfortknox/msb-client-websocket-python/build.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/build.yml:52: update your workflow using https://app.stepsecurity.io/secureworkflow/research-virtualfortknox/msb-client-websocket-python/build.yml/master?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/build.yml:71: update your workflow using https://app.stepsecurity.io/secureworkflow/research-virtualfortknox/msb-client-websocket-python/build.yml/master?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/build.yml:74: update your workflow using https://app.stepsecurity.io/secureworkflow/research-virtualfortknox/msb-client-websocket-python/build.yml/master?enable=pin","Warn: pipCommand not pinned by hash: .github/workflows/build.yml:27","Warn: pipCommand not pinned by hash: .github/workflows/build.yml:28","Warn: pipCommand not pinned by hash: .github/workflows/build.yml:57","Warn: pipCommand not pinned by hash: .github/workflows/build.yml:58","Info:   0 out of   4 GitHub-owned GitHubAction dependencies pinned","Info:   0 out of   2 third-party GitHubAction dependencies pinned","Info:   0 out of   4 pipCommand dependencies pinned"],"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: Apache License 2.0: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'master'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"Vulnerabilities","score":10,"reason":"0 existing vulnerabilities detected","details":null,"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}}]},"last_synced_at":"2025-08-23T02:24:31.399Z","repository_id":34925378,"created_at":"2025-08-23T02:24:31.399Z","updated_at":"2025-08-23T02:24:31.399Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28417511,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-14T10:25:19.714Z","status":"ssl_error","status_checked_at":"2026-01-14T10:22:49.371Z","response_time":107,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["msb","msb-client","msb-client-websocket","python","websocket-interface"],"created_at":"2026-01-14T10:32:49.268Z","updated_at":"2026-01-14T10:32:49.319Z","avatar_url":"https://github.com/research-virtualfortknox.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://research.virtualfortknox.de\" target=\"_blank\" rel=\"noopener noreferrer\"\u003e\n    \u003cimg src=\"https://research.virtualfortknox.de/static/cms/img/vfk_research_logo.png\" alt=\"VFK Research Logo\" height=\"70\" \u003e\n  \u003c/a\u003e\n\u003c/p\u003e\n\n# MSB websocket client library for Python\n\n![Build Status](https://github.com/research-virtualfortknox/msb-client-websocket-python/actions/workflows/build.yml/badge.svg)\n[![PyPI version](https://badge.fury.io/py/msb-client-websocket-python.svg)](https://badge.fury.io/py/msb-client-websocket-python)\n[![Coverage Status](https://coveralls.io/repos/github/research-virtualfortknox/msb-client-websocket-python/badge.svg?branch=feature-coveralls)](https://coveralls.io/github/research-virtualfortknox/msb-client-websocket-python?branch=feature-coveralls)\n[![FOSSA Status](https://app.fossa.io/api/projects/git%2Bgithub.com%2Fresearch-virtualfortknox%2Fmsb-client-websocket-python.svg?type=shield)](https://app.fossa.io/projects/git%2Bgithub.com%2Fresearch-virtualfortknox%2Fmsb-client-websocket-python?ref=badge_shield)\n\n**Compatibility Matrix**\n\nClient version compatibility to MSB versions:\n\n| | **1.5.x-RELEASE** | **1.6.x-RELEASE** |\n|---|:---:|:---:|\n| 1.0.x       | x | x |\n\n## Welcome\n\nIf you want to contribute, please read the [Contribution Guidelines](.github/CONTRIBUTING.md).\n\nIf you want to test this client by using its sources and a sample app, read the [App Sample](doc/app_sample.md).\n\nIf you want to know how to use this client in your own project, read below.\n\n## What is VFK MSB\n\nTODO: Link to general documentation about VFK MSB\n\nYou can use this client to connect a python app to VFK MSB.\n\n## Prerequisites\n\n* Setup [Python](https://www.python.org/downloads/) **version 3.9.x**\n  * last client version supporting Python 2.7 is v1.0.8\n  * last client version supporting Python 3.6 is v1.0.11\n  * last client version supporting Python 3.7 is v1.0.13\n  * last client version supporting Python 3.8 is v1.0.15\n* MSB client installed using PyPi\n* Optional: Use pipenv to run your python app in a virtual environment to avoid dependency isssues with other apps\n\nInstall MSB client from PyPi\n\n```sh\npip install msb-client-websocket-python\n```\n\nImport to your applicaton\n\n```python\nfrom msb_client.ComplexDataFormat import ComplexDataFormat\nfrom msb_client.DataType import DataType\nfrom msb_client.Event import Event\nfrom msb_client.Function import Function\nfrom msb_client.MsbClient import MsbClient\n```\n\n## Create self-description\n\nThe figure below shows a minimal required `self-description model` of a smart object / application.\nEvery smart object / application requires (must have) a uuid and a token.\nThe uuid is competent for identification\nand the token is used to verify the smart object / application for its owner on the MSB side.\n\n![Self Description](doc/images/self-description.png)\n\nTODO: Here you can find more information about\nthe `self-description structure` and `supported data formats`.\n\n### Alternative 1 - By application.properties\n\nAdd the main description by adding an `application.poperties` file to the root of your project:\n\nGenerate the uuid e.g. by a tool like https://www.uuidgenerator.net/\n\n```sh\nmsb.uuid=76499d88-34cf-4836-8cc1-7e0d9c54dacx\nmsb.name=YourSmartObjectName\nmsb.description=YourSmartObjectDesc\nmsb.token=5e0d9c54dacx\nmsb.type=SmartObject\n```\n\nWhen initializing your msb client instance, the `application.properties` file will be loaded.\n\n```python\nmyMsbClient = MsbClient()\n```\n\nYou can also set a custom path to the `application.properties` file.\n\n```python\nmyMsbClient = MsbClient(applicationPropertiesCustomPath=\"./your/path/to/application.properties\")\n```\n\n### Alternative 2 - By constructor\n\nIf you do not provide an application.properties file, use the constructor\nto define the basic self description.\n\n```python\nSERVICE_TYPE = \"SmartObject\"\nSO_UUID = str(uuid.uuid1()) # you can type in an own uuid here instead of generating it\nSO_NAME = \"YourSmartObjectName\"\nSO_DESCRIPTION = \"YourSmartObjectDesc\"  \nSO_TOKEN = SO_UUID[-6:]\nmyMsbClient = MsbClient(\n    SERVICE_TYPE,\n    SO_UUID,\n    SO_NAME,\n    SO_DESCRIPTION,\n    SO_TOKEN,\n)\n```\n\n## Add Events\n\nAdd `events` to your smart object / application which can be send to MSB.\n\n### Alternative 1: Simple event creation sample (using method params):\n\n```python\nevent_id = \"E1\"\nevent_name = \"EVENT \" + event_id\nevent_description = \"EVENT Description \" + event_id\nevent_dataformat = DataType.STRING\nevent_priority = 1 # 0 (LOW), 1 (MEDIUM), 2 (HIGH)\nisArray = False # just one value or array of it?\n\n# add the event\nmyMsbClient.addEvent(\n    event_id,\n    event_name,\n    event_description,\n    event_dataformat,\n    event_priority,\n    isArray,\n)\n```\n\n### Alternative 2: Complex event creation sample (using object):\n\n```python\nevent_id = \"E2\"\nevent_name = \"EVENT \" + event_id\nevent_description = \"EVENT Description \" + event_id\nevent_priority = 1 # 0 (LOW), 1 (MEDIUM), 2 (HIGH)\nisArray = False # just one value or array of it?\n\n# define a complex data format to be used in an event\n# init the complex data format\nmyDevice = ComplexDataFormat(\"MyDevice\")\nmyModule = ComplexDataFormat(\"MyModule\")\n\n# add the properties to the complex objects\n# (property_name, property_datatype, isArray)\nmyModule.addProperty(\"moduleName\", DataType.STRING, False)\nmyDevice.addProperty(\"deviceName\", DataType.STRING, False)\nmyDevice.addProperty(\"deviceWeight\", DataType.FLOAT, False)\nmyDevice.addProperty(\"submodules\", myModule, True)\n\n# add the event (with the root of the nested complex object)\nmyMsbClient.addEvent(\n    event_id,\n    event_name,\n    event_description,\n    myDevice,\n    event_priority,\n    isArray,\n)\n```\n\n### Alternative 3: Complex event creation sample (using json object):\n\n```python\nevent_id = \"E3\"\nevent_name = \"EVENT \" + event_id\nevent_description = \"EVENT Description \" + event_id\nevent_priority = 1 # 0 (LOW), 1 (MEDIUM), 2 (HIGH)\nisArray = False # just one value or array of it?\n\n# add the event (with the MSB-ready json object)\nmyMsbClient.addEvent(\n    event_id,\n    event_name,\n    event_description,\n    {\n        \"Team\" : {\n            \"type\" : \"object\",\n            \"properties\" : {\n                \"staff\" : {\n                    \"type\" : \"array\",\n                    \"items\" : {\n                        \"$ref\" : \"#/definitions/Member\"\n                    }\n                }\n            }\n        },\n        \"Member\" : {\n            \"type\" : \"object\",\n            \"properties\" : {\n                \"name\" : {\n                    \"type\" : \"string\"\n                },\n                \"status\" : {\n                    \"enum\" : [ \"present\", \"absent\" ],\n                    \"type\" : \"string\"\n                }\n            }\n        },\n        \"dataObject\" : {\n            \"$ref\" : \"#/definitions/Team\"\n        }\n    },\n    event_priority,\n    isArray,\n)\n```\n\nSee `app_sample.py` for more event creation examples.\n\n## Add Functions\n\nAdd `functions` and their implementations your smart object / application is able to handle.\n\n### Alternative 1: Simple function creation sample (using method params):\n\n```python\nfunction_id = \"F1\"\nfunction_name = \"FUNC \" + function_id\nfunction_description = \"FUNC Description \" + function_id\nfunction_dataformat = DataType.STRING\nisArray = False # handle array of values or just one value?\nresponseEvents = None # you can link to response events here by a list of event is e.g. [\"E1\"]\n\n# define the function which will be passed to the function description\n# this function implementation will be called\ndef printMsg(msg):\n    print(str(msg[\"dataObject\"]))\n\n# add the function\nmyMsbClient.addFunction(\n    function_id,\n    function_name,\n    function_description,\n    function_dataformat,\n    printMsg,\n    isArray,\n    responseEvents,\n)\n```\n\n### Alternative 2: Complex function creation sample (using object):\n\n```python\nfunction_id = \"F2\"\nfunction_name = \"FUNC \" + function_id\nfunction_description = \"FUNC Description \" + function_id\nisArray = False # handle array of values or just one value?\nresponseEvents = None # you can link to response events here by a list of event is e.g. [\"E1\"]\n\n# define a complex data format to be used in an event\n# init the complex data format\nmyCar = ComplexDataFormat(\"MyCar\")\n\n# add the properties to the complex objects\n# (property_name, property_datatype, isArray)\nmyCar.addProperty(\"carColor\", DataType.STRING, False)\nmyCar.addProperty(\"carNrOfSeats\", DataType.INT32, False)\nmyCar.addProperty(\"carWeight\", DataType.FLOAT, False)\n\n# define the function which will be passed to the function description\n# this function implementation will be called\ndef printMsg(msg):\n    print(str(msg[\"dataObject\"]))\n\n# add the function\nmyMsbClient.addFunction(\n    function_id,\n    function_name,\n    function_description,\n    myCar,\n    printMsg,\n    isArray,\n    responseEvents,\n)\n```\n\n### Alternative 3: Complex function creation sample (using json object):\n\n```python\nfunction_id = \"F3\"\nfunction_name = \"FUNC \" + function_id\nfunction_description = \"FUNC Description \" + function_id\nisArray = False # handle array of values or just one value?\nresponseEvents = None # you can link to response events here by a list of event is e.g. [\"E1\"]\n\n# define the function which will be passed to the function description\n# this function implementation will be called\ndef printMsg(msg):\n    print(str(msg[\"dataObject\"]))\n\n# add the function\nmyMsbClient.addFunction(\n    function_id,\n    function_name,\n    function_description,\n    {\n        \"MyCar\" : {\n            \"type\" : \"object\",\n            \"properties\" : {\n                \"carColor\" : {\n                    \"type\" : \"string\"\n                },\n                \"carNrOfSeats\" : {\n                    \"format\": \"int32\",\n                    \"type\": \"integer\"\n                },\n                \"carWeight\" : {\n                    \"format\": \"float\",\n                    \"type\": \"number\"\n                },\n                \"wheels\" : {\n                    \"type\" : \"array\",\n                    \"items\" : {\n                        \"$ref\" : \"#/definitions/MyWheel\"\n                    }\n                }\n            }\n        },\n        \"MyWheel\" : {\n            \"type\" : \"object\",\n            \"properties\" : {\n                \"position\" : {\n                    \"enum\" : [ \"br\", \"bl\", \"fr\", \"fl\" ],\n                    \"type\" : \"string\"\n                }\n            }\n        },\n        \"dataObject\" : {\n            \"$ref\" : \"#/definitions/MyCar\"\n        }\n    },\n    printMsg,\n    isArray,\n    responseEvents,\n)\n```\n\nSee `app_sample.py` of the application template for more (and complex) examples.\n\n## Connect and Register Client\n\n```python\nmsb_url = 'ws://127.0.0.1:8085'\nmyMsbClient.connect(msb_url)\nmyMsbClient.register()\n```\n\nYou will get an `IO_CONNECTED` and `IO_REGISTERED` event from MSB, if successful.\n\n## Event publishing\n\nFor publishing an event to a websocket broker interface,\nonly the `eventId` and `data` are required of the already specified event (see above).\n\n```python\nevent_id = \"E1\"\nevent_value = 'Hello World!'\n\nmyMsbClient.publish(\n  event_id, \n  event_value\n)\n```\n\nThe MSB responds with an `IO_PUBLISHED` event, if successful.\n\nBy default events are published with a low priority.\n\nIt is also possible to `set the priority` of an event.\n\nThere are three possible priorities for events like it is shown at the following table.\n\n| `Constant` | `Value` |\n|:---:|:---:|\n| LOW | 0 |\n| MEDIUM| 1 |\n| HIGH| 2 |\n\n```python\nevent_id = \"E1\"\nevent_value = 'Hello World!'\nevent_priority = 2\n\nmyMsbClient.publish(\n  event_id, \n  event_value,\n  event_priority\n)\n```\n\nAnother option is to publish an event as `cached event` by setting the cache parameter to true.\nAnd you can add a `post date`.\n\nThis means that the event is not deleted if the connection is broken.\n\n```python\nevent_id = \"E1\"\nevent_value = 'Hello World!'\nevent_priority = 2\nevent_isCached = True\nevent_postDate = datetime.datetime.utcnow().isoformat()[:-3] + \"Z\"\n\nmyMsbClient.publish(\n  event_id, \n  event_value,\n  event_priority,\n  event_isCached,\n  event_postDate\n)\n```\n\nYou cann also handle `correlation ids` to identify an event among flows.\n\n```python\nevent_id = \"E1\"\nevent_value = 'Hello World!'\nevent_priority = 2\nevent_isCached = True\nevent_postDate = datetime.datetime.utcnow().isoformat()[:-3] + \"Z\"\nevent_correlationId = \"72047f33-a9ae-4aa5-b7ae-c1c4a2797cac\"\n\nmyMsbClient.publish(\n  event_id, \n  event_value,\n  event_priority,\n  event_isCached,\n  event_postDate,\n  event_correlationId\n)\n```\n\nFor values based on complex data formats it will look like this:\n\n```python\nevent_id = \"E2\"\nevent_priority = 2\nevent_isCached = True\nevent_postDate = datetime.datetime.utcnow().isoformat()[:-3] + \"Z\"\nevent_correlationId = \"72047f33-a9ae-4aa5-b7ae-c1c4a2797cac\"\n\n# pepare the complex ovbject based on a complex data format\n# use it as event value\nmyModuleObj = {}\nmyModuleObj['moduleName'] = 'Module 1'\nmyDeviceObj = {}\nmyDeviceObj['deviceName'] = 'Device 1'\nmyDeviceObj['deviceWeight'] = 1.3\nmyDeviceObj['submodules'] = [myModuleObj]\n\nmyMsbClient.publish(\n  event_id, \n  myDeviceObj,\n  event_priority,\n  event_isCached,\n  event_postDate,\n  event_correlationId\n)\n```\n\n## Function call handling\n\nAs shown above the addFunction method includes a `function pointer`\nto point to the function implementation.\n\n## Configuration parameters\n\nConfiguration parameters are a simple list of key value pairs for the smart object / application.\nIt is displayed and can be customized in the MSB UI to change your apps behaviour during runtime.\n\n`Add` condifuration parameters:\n\n```python\nparam_name_1 = \"testParam1\"\nparam_value_1 = True\nparam_datatype_1 = DataType.BOOLEAN\nmyMsbClient.addConfigParameter(param_name_1, param_value_1, param_datatype_1)\n\nparam_name_2 = \"testParam2\"\nparam_value_2 = \"StringValue\"\nparam_datatype_2 = DataType.STRING\nmyMsbClient.addConfigParameter(param_name_2, param_value_2, param_datatype_2)\n\nparam_name_3 = \"testParam3\"\nparam_value_3 = 1000\nparam_datatype_3 = DataType.INT32\nmyMsbClient.addConfigParameter(param_name_3, param_value_3, param_datatype_3)\n```\n\n`Get` configuration parameter (after changed in MSB UI) to change your app behaviour:\n\n```python\n# get by getConfigParameter using name as key\nparameterValueFound_1 = myMsbClient.getConfigParameter(param_name_1)\nparameterValueFound_2 = myMsbClient.getConfigParameter(param_name_2)\nparameterValueFound_3 = myMsbClient.getConfigParameter(param_name_3)\n```\n\n## SSL/TLS connection configuration\n\nTo enable `SSL/TLS`, you need to specify wss:// or https:// in the URL instead of ws:// or http://.\n\nFurthermore, it is necessary to specify a trust store in the client,\nwhich contains the public certificate of the MSB interface, so that it is considered trustworthy.\n\n```python\nmsb_url = 'wss://\u003chostname\u003e:\u003cport\u003e'\nmyMsbClient.connect(msb_url)\nmyMsbClient.register()\n```\n\nIf you use an IP instead of a public url during development,\nit will be necessary to disable the hostname verification to connect via web socket secure.\n\n```python\nmyMsbClient.disableHostnameVerification(True)  \n```\n\n## Connection recovery\n\nIf connection to the common websocket interface is broken the client performs a reconnect.\n\nAfter a reconnect the registration at the MSB will be redone automatically by the client.\n\nYou can change this interval by setting an integer value in `ms` for the reconnect interval.\n\n```python\nmyMsbClient.setReconnectInterval(10000)\n```\n\nOr you can disable the automatic reconnect.\n\n```python\nmyMsbClient.disableAutoReconnect(True)\n```\n\n## Event caching\n\nIf the client loses the connection, the published events are cached in a queue.\n\nAfter a successfull reconnection, the queued events are published to MSB (FIFO principle).\nThe default size of the queue is 1000 entries. The size can be changed:\n\n```python\nmyMsbClient.setEventCacheSize(1000)\n```\n\nIf no event caching is needed, you can disable it.\n\n```python\nmyMsbClient.disableEventCache(True)\n```\n\n## Debug mode\n\nTo debug your clients communication with MSB, you can enable the debug mode\n\n```python\nmyMsbClient.enableDebug(True)\n```\n\nTo enable the trace of the websocket communication use also\n\n```python\nmyMsbClient.enableTrace(True)\n```\n\nIt mgiht be also helpful to enable data format validation, to check if an event value is valid\n\n```python\nmyMsbClient.enableDataFormatValidation(True)\n```\n\n\n## License\n[![FOSSA Status](https://app.fossa.io/api/projects/git%2Bgithub.com%2Fresearch-virtualfortknox%2Fmsb-client-websocket-python.svg?type=large)](https://app.fossa.io/projects/git%2Bgithub.com%2Fresearch-virtualfortknox%2Fmsb-client-websocket-python?ref=badge_large)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fresearch-virtualfortknox%2Fmsb-client-websocket-python","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fresearch-virtualfortknox%2Fmsb-client-websocket-python","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fresearch-virtualfortknox%2Fmsb-client-websocket-python/lists"}