[![Build Status](https://img.shields.io/circleci/build/github/Jaxc/PyStageLinQ/main?style=plastic)](https://app.circleci.com/pipelines/github/Jaxc/PyStageLinQ?branch=main)
[![PyPI - Python Version](https://img.shields.io/pypi/pyversions/PyStageLinQ?style=plastic)](https://pypi.org/project/PyStageLinQ/)
<picture>
<img alt="PyPi version" src="https://img.shields.io/pypi/v/PyStageLinQ?style=plastic">
</picture>
[![PyPI - License](https://img.shields.io/pypi/l/PyStageLinQ?style=plastic)](https://en.wikipedia.org/wiki/MIT_License)
[![Read the Docs](https://img.shields.io/readthedocs/pystagelinq?style=plastic)](https://pystagelinq.readthedocs.io/en/latest/)
[![Codecov](https://img.shields.io/codecov/c/github/Jaxc/PyStageLinQ?style=plastic)](https://app.codecov.io/gh/Jaxc/PyStageLinQ)
[![CodeFactor](https://www.codefactor.io/repository/github/jaxc/pystagelinq/badge/main?style=plastic)](https://www.codefactor.io/repository/github/jaxc/pystagelinq/overview/main)
[![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black)
# Overview
This Python module decodes part of the StageLinQ protocol used by Denon DJ equipment. In its current state it is
possible to read out information like track information, fader position (Crossfader, channel volume, pitchfader), BPM
etc. The project also includes [a description of how StageLinQ works](https://github.com/Jaxc/PyStageLinQ/blob/main/StageLinQ_protocol.md) taking from my findings
as well as other code available.
This module can be used to receive this information from a device via a callback when data is available.
There is also a Wireshark Dissector that I made during my trials.
# Status
An initial implementation of parts of the protocol has been done, but there is still much left to do. As the code should
be at least somewhat functional I've decided to release this as is and add functionality along the way. Since I'm unsure
where this is heading there is a possibility that there will be a future (major) version that will reimagine the
functions completely.
The next few versions will probably be patched to bring the documentation up to date.
# Documentation
Documentation is available on [readthedocs.io](https://pystagelinq.readthedocs.io/en/latest/)
# Installation
`pip install PyStageLinQ`
# Issue tracking
If you find an issue, please report check known issues, and if the issue is not mentioned please report it
[here](https://github.com/Jaxc/PyStageLinQ)
# Example usage
Here follow an example of how PyStageLinQ can be used:
```python
from PyStageLinQ import EngineServices, PyStageLinQ
PrimeGo = None
# Callback for when PyStageLinQ as found a StageLinQ device. This will print out information about the found device
# and if lets the user decide if they want to subscribe to a service or not.
def new_device_found_callback(ip, discovery_frame, service_list):
# Print device info and supplied services
print(
f"Found new Device on ip {ip}: Device name: {discovery_frame.device_name}, ConnectionType: {discovery_frame.connection_type}, SwName: {discovery_frame.sw_name}, "
f"SwVersion: {discovery_frame.sw_version}, port: {discovery_frame.Port}")
if len(service_list) > 0:
print("Services found in device:")
else:
print("No services found")
for service in service_list:
print(f"\t{service.service} on port {service.port}")
# Request StateMap service
for service in service_list:
if service.service == "StateMap":
PrimeGo.subscribe_to_statemap(service, EngineServices.prime_go, state_map_data_print)
# Callback for when data has arrived from a StageLinQ device. It is up to the user what to do with this information.
def state_map_data_print(data):
for message in data:
print(message)
# Example main function, starting PyStageLinQ.
if __name__ == "__main__":
global PrimeGo
# Run PyStageLinQ on all available network interfaces
PrimeGo = PyStageLinQ.PyStageLinQ(new_device_found_callback, name="Jaxcie StagelinQ")
PrimeGo.start()
```
# Wireshark dissector
When I developed this code I made a WireShark Dissector, it is included in this repo. Do note that this dissector
isn't properly tested and may cause unexpected issues. As this file is not part of the Pythoncode in PyStageLinQ it can
be found on [GitHub](https://github.com/Jaxc/PyStageLinQ/blob/main/tools/StageLinQ.lua)
# Compatability
PyStageLinQ has been tested with a Denon DJ Prime Go on Windows 10 and Linux (Mint 20.3) with Python 3.10.
# Acknowledgements
Big thanks to icedream for his implementation of StageLinQ in go:
https://github.com/icedream/go-stagelinq
Raw data
{
"_id": null,
"home_page": null,
"name": "PyStageLinQ",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.10",
"maintainer_email": null,
"keywords": "DJ, Denon DJ, Prime Go, StageLinQ, Streaming, VJ",
"author": null,
"author_email": "jaxc@skrooter.com",
"download_url": "https://files.pythonhosted.org/packages/f6/e3/f1f434e934a6cdbb141d71ed4e4b7b9d2a9eba37557585aaf65d033b28c8/pystagelinq-0.2.1.tar.gz",
"platform": null,
"description": "[![Build Status](https://img.shields.io/circleci/build/github/Jaxc/PyStageLinQ/main?style=plastic)](https://app.circleci.com/pipelines/github/Jaxc/PyStageLinQ?branch=main)\n[![PyPI - Python Version](https://img.shields.io/pypi/pyversions/PyStageLinQ?style=plastic)](https://pypi.org/project/PyStageLinQ/)\n<picture>\n <img alt=\"PyPi version\" src=\"https://img.shields.io/pypi/v/PyStageLinQ?style=plastic\">\n</picture>\n[![PyPI - License](https://img.shields.io/pypi/l/PyStageLinQ?style=plastic)](https://en.wikipedia.org/wiki/MIT_License)\n[![Read the Docs](https://img.shields.io/readthedocs/pystagelinq?style=plastic)](https://pystagelinq.readthedocs.io/en/latest/)\n[![Codecov](https://img.shields.io/codecov/c/github/Jaxc/PyStageLinQ?style=plastic)](https://app.codecov.io/gh/Jaxc/PyStageLinQ)\n[![CodeFactor](https://www.codefactor.io/repository/github/jaxc/pystagelinq/badge/main?style=plastic)](https://www.codefactor.io/repository/github/jaxc/pystagelinq/overview/main)\n[![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black)\n# Overview\nThis Python module decodes part of the StageLinQ protocol used by Denon DJ equipment. In its current state it is\npossible to read out information like track information, fader position (Crossfader, channel volume, pitchfader), BPM \netc. The project also includes [a description of how StageLinQ works](https://github.com/Jaxc/PyStageLinQ/blob/main/StageLinQ_protocol.md) taking from my findings\nas well as other code available.\n\nThis module can be used to receive this information from a device via a callback when data is available.\n\nThere is also a Wireshark Dissector that I made during my trials.\n\n# Status\nAn initial implementation of parts of the protocol has been done, but there is still much left to do. As the code should\nbe at least somewhat functional I've decided to release this as is and add functionality along the way. Since I'm unsure\nwhere this is heading there is a possibility that there will be a future (major) version that will reimagine the \nfunctions completely.\n\nThe next few versions will probably be patched to bring the documentation up to date.\n\n# Documentation\nDocumentation is available on [readthedocs.io](https://pystagelinq.readthedocs.io/en/latest/)\n\n# Installation\n`pip install PyStageLinQ`\n\n\n# Issue tracking\nIf you find an issue, please report check known issues, and if the issue is not mentioned please report it \n[here](https://github.com/Jaxc/PyStageLinQ)\n\n# Example usage\nHere follow an example of how PyStageLinQ can be used:\n\n```python\nfrom PyStageLinQ import EngineServices, PyStageLinQ\nPrimeGo = None\n\n# Callback for when PyStageLinQ as found a StageLinQ device. This will print out information about the found device\n# and if lets the user decide if they want to subscribe to a service or not.\n\ndef new_device_found_callback(ip, discovery_frame, service_list):\n # Print device info and supplied services\n print(\n f\"Found new Device on ip {ip}: Device name: {discovery_frame.device_name}, ConnectionType: {discovery_frame.connection_type}, SwName: {discovery_frame.sw_name}, \"\n f\"SwVersion: {discovery_frame.sw_version}, port: {discovery_frame.Port}\")\n\n if len(service_list) > 0:\n print(\"Services found in device:\")\n else:\n print(\"No services found\")\n\n for service in service_list:\n print(f\"\\t{service.service} on port {service.port}\")\n\n\n # Request StateMap service\n for service in service_list:\n if service.service == \"StateMap\":\n PrimeGo.subscribe_to_statemap(service, EngineServices.prime_go, state_map_data_print)\n\n \n# Callback for when data has arrived from a StageLinQ device. It is up to the user what to do with this information.\n \ndef state_map_data_print(data):\n for message in data:\n print(message)\n\n# Example main function, starting PyStageLinQ.\nif __name__ == \"__main__\":\n global PrimeGo\n \n # Run PyStageLinQ on all available network interfaces\n PrimeGo = PyStageLinQ.PyStageLinQ(new_device_found_callback, name=\"Jaxcie StagelinQ\")\n PrimeGo.start()\n```\n\n# Wireshark dissector\nWhen I developed this code I made a WireShark Dissector, it is included in this repo. Do note that this dissector \nisn't properly tested and may cause unexpected issues. As this file is not part of the Pythoncode in PyStageLinQ it can\nbe found on [GitHub](https://github.com/Jaxc/PyStageLinQ/blob/main/tools/StageLinQ.lua)\n\n# Compatability\nPyStageLinQ has been tested with a Denon DJ Prime Go on Windows 10 and Linux (Mint 20.3) with Python 3.10. \n\n# Acknowledgements\nBig thanks to icedream for his implementation of StageLinQ in go:\nhttps://github.com/icedream/go-stagelinq\n",
"bugtrack_url": null,
"license": null,
"summary": "A Python implementation of a StagelinQ protocol",
"version": "0.2.1",
"project_urls": {
"Bug Tracker": "https://github.com/Jaxc/PyStageLinQ/issues",
"Documentation": "https://pystagelinq.readthedocs.io/en/latest/",
"Funding": "https://ko-fi.com/jaxcie",
"Homepage": "https://github.com/Jaxc/PyStageLinQ"
},
"split_keywords": [
"dj",
" denon dj",
" prime go",
" stagelinq",
" streaming",
" vj"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "df38787e3baa2db1edd71ec0de0bbf0c8fd254247a4618b578be5db66cbd6e50",
"md5": "0a891ba621fdb89c5a7aeb1a962b94fb",
"sha256": "39ea5e47a8746e1cc82e47caa3aea2adcd8916d7f8f538b36fb2b5381e71b2a4"
},
"downloads": -1,
"filename": "pystagelinq-0.2.1-py3-none-any.whl",
"has_sig": false,
"md5_digest": "0a891ba621fdb89c5a7aeb1a962b94fb",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.10",
"size": 18406,
"upload_time": "2024-08-12T12:52:07",
"upload_time_iso_8601": "2024-08-12T12:52:07.713883Z",
"url": "https://files.pythonhosted.org/packages/df/38/787e3baa2db1edd71ec0de0bbf0c8fd254247a4618b578be5db66cbd6e50/pystagelinq-0.2.1-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "f6e3f1f434e934a6cdbb141d71ed4e4b7b9d2a9eba37557585aaf65d033b28c8",
"md5": "0df0fc145dcb50cdf63b1cdb2c91301b",
"sha256": "11bc030dfd1f25b2dcf76d7203e5f5e28fe68270e9caa2c79435b185193d95ae"
},
"downloads": -1,
"filename": "pystagelinq-0.2.1.tar.gz",
"has_sig": false,
"md5_digest": "0df0fc145dcb50cdf63b1cdb2c91301b",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.10",
"size": 36898,
"upload_time": "2024-08-12T12:52:09",
"upload_time_iso_8601": "2024-08-12T12:52:09.035001Z",
"url": "https://files.pythonhosted.org/packages/f6/e3/f1f434e934a6cdbb141d71ed4e4b7b9d2a9eba37557585aaf65d033b28c8/pystagelinq-0.2.1.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2024-08-12 12:52:09",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "Jaxc",
"github_project": "PyStageLinQ",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"circle": true,
"test_requirements": [],
"lcname": "pystagelinq"
}