Code Monkey home page Code Monkey logo

mattipv4 / pydmxcontrol Goto Github PK

View Code? Open in Web Editor NEW
107.0 9.0 21.0 15.04 MB

A Python 3 module to control DMX using OpenDMX or uDMX - Featuring fixture profiles, built-in effects and a web control panel.

Home Page: https://pypi.org/project/PyDMXControl/

License: GNU General Public License v3.0

Python 80.22% JavaScript 1.61% CSS 2.97% Jinja 15.21%
dmx python python3 lighting theater fixtures python-3 python-library dmx512 dmx-interface dmx-channels dmx-dimmer dmx-library python-script control-dmx controller fixture-profiles udmx opendmx open-dmx

pydmxcontrol's Introduction

PyDMXControl

A Python 3 module to control DMX using OpenDMX or uDMX - Featuring fixture profiles, built-in effects and a web control panel.

PyPi Version License Python Versions Code Size

GitHub Sponsors Patreon Slack

Scrutinizer Code Quality Build Status

PyDMXControl Icon


Installation

Install via pip (recommended)

pip install -U PyDMXControl

Install via pip with audio support

pip install -U PyDMXControl[audio]

Install via GitHub (development version, with audio)

pip install -U git+https://github.com/MattIPv4/PyDMXControl#egg=PyDMXControl[audio]

Features

  • FIXTURE profiles per manufacturer (see all included profiles)

    • Generic dimmer fixture included, single channel
    • RGB (3-channel) fixture with virtual dimmer built-in
  • EFFECT module/library support (see all packaged effects)

    • Intensity dim chase provided, configurable speed and offset provided
    • Included is a fixture color chase effect, unlimited number of colors supported
    • Effects can be applied to individual fixtures or multiple as a group
  • OpenDMX and uDMX works out of the box

    • Package developed on and tested extensively with a uDMX system
    • OpenDMX (FTDI) controller also provided, as well as direct serial
    • Extensible for custom transmitting controllers
  • CUSTOM callbacks supported with an internal ticker

    • Have actions take place on their own at certain times using the callback ticker
  • THREADED to allow continuous runtime

    • Run your own blocking scripts whilst PyDMXControl continues to output data
  • WEBSITE control panel built in

    • Global and individual fixture intensity control via sliders
    • Quick access to callback functions globally and for each fixture
    • Color picker for individual fixtures as well as specific channel control
  • JSON fixture configurations

    • Load fixture configurations from JSON files into the controller
    • Save your current set of fixtures out to JSON files for later use
  • Optional AUDIO playback supported

    • Play audio tracks whilst PyDMXControl continues to run lighting control
    • Uses pygame for best cross-platform and audio format support

Example Usage

An example of how to get a single dimmer working with PyDMXControl, providing the web control panel and the console debug system once started.

# Import the OpenDMX or uDMX controller from PyDMXControl,
#  this will be how the data is outputted.
from PyDMXControl.controllers import OpenDMXController
# from PyDMXControl.controllers import uDMXController

# Import the fixture profile we will use,
#  the simple Dimmer in this example.
from PyDMXControl.profiles.Generic import Dimmer

# Create an instance of the uDMX controller, 
#  this holds all the fixture information and outputs it.
# This will start outputting data immediately.
dmx = OpenDMXController()
# dmx = uDMXController()

# Add a new Dimmer fixture to our controller
#  and save it to a variable so we can access it.
# We give it a name so it's easier to identify in the debug control options.
fixture = dmx.add_fixture(Dimmer, name="My_First_Dimmer")

# Next, dim the intensity of the fixture from it's initial value of zero
#  to full, which is represented as 255 in DMX.
# This is done over 5000 milliseconds, or 5 seconds.
fixture.dim(255, 5000)

# We can now start the web control panel built into PyDMXControl.
# This will output the web address in console, but should be http://0.0.0.0:8080
# This runs in the background and so we can continue to do other things still.
dmx.web_control()

# The console debug mode can also be started if required,
#  this provides basic control options in the console of the program.
# This is blocking however and so the script will not continue past here until
#  the debug control is exited. This won't stop DMX output.
dmx.debug_control()

# Once the console debug mode is exited the script will continue, to stop it
#  exiting and stopping DMX output when can use a built-in sleep function.
# This sleep function will wait until enter is pressed in the console before continuing.
dmx.sleep_till_enter()

# With everything done, you can terminate the DMX output and the program by calling
#  the close method of the controller.
# This will cleanly close any threads in use and stop DMX output.
dmx.close()

For a "real life" example, please take a look at my home automation office lighting script.

What is the point of this?

Just messing around with using Python to control/send DMX.
Supports fixture profiling; Has defaults for a standard fixture and fixtures that need virtual dimmers.
Prebuilt profiles for generic fixtures (Single dimmer, RGB LED, Custom (set your own number of channels)).

Has a debug shell that allows control of fixture channel values and access to general callbacks. Additionally, provides an advanced web control panel with access to global callbacks, fixture helpers, fixture colors and control over individual fixture channels.

Currently, output is supported via OpenDMX, uDMX or raw serial.
If someone wants to buy me an Enttec USB DMX Pro then I'll try make it work with that too.

Thank you to Dave Hocker, author of pyudmx, for his work on pyudmx and his advice via email in solving some of the issues making this library behave with uDMX.

Contributing

Contributions are always welcome to this project!
Take a look at any existing issues on this repository for starting places to help contribute towards, or simply create your own new contribution to the project.

Please make sure to follow the existing standards within the project such as code styles, naming conventions and commenting/documentation.

When you are ready, simply create a pull request for your contribution and I will review it whenever I can!

Donating

You can also help me and the project out by sponsoring me through GitHub Sponsors (preferred), contributing through a donation on PayPal or by supporting me monthly on my Patreon page.

GitHub Sponsors Patreon PayPal

Discussion, Support and Issues

Need support with this project, have found an issue or want to chat with others about contributing to the project?

Please check the project's issues page first for support & bugs!

Not found what you need here?

  • If you have an issue, please create a GitHub issue here to report the situation, include as much detail as you can!
  • or, You can join our Slack workspace to discuss any issue, to get support for the project or to chat with contributors and myself:
Slack

pydmxcontrol's People

Contributors

crscheid avatar lndr avatar mattipv4 avatar oxy avatar superpuffin avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

pydmxcontrol's Issues

Node-RED Controller

Hi Matt.

I'm looking for way to control my DMX decoder using RS485 hat on Rpi. I'd love to control it in Node-RED environment.
Shield's manufacturer supplied a sample python code, sending a simple test string over RS485, and it works, but I'm wandering how can I modify this code, making it send DMX frames. Maybe you could give me some tips how to do it, because unfortunately, I don't know python.

Here is the code which I've simplified a little bit, and original one in the link below.

import serial
import os
import sys
import logging

logging.basicConfig(level=logging.INFO)
libdir = os.path.join(os.path.dirname(os.path.dirname(os.path.realpath(file))), 'lib')
if os.path.exists(libdir):
sys.path.append(libdir)

import RPi.GPIO as GPIO
import time
from waveshare_2_CH_RS485_HAT import config

TXDEN_1 = 27
TXDEN_2 = 22

ser = config.config(dev = "/dev/ttySC0")
data = ''
GPIO.output(TXDEN_1, GPIO.LOW)
ser.Uart_SendString('Waveshare 2-CH RS485 HAT\r\n')
time.sleep(0.005)#Waiting to send
GPIO.output(TXDEN_1, GPIO.HIGH)

https://www.waveshare.com/wiki/2-CH_RS485_HAT

Regards,
Paweล‚

Using `ftdi_vendor_id`/`ftdi_product_id` in `OpenDMXController`?

          You might want to pass `ftdi_vendor_id` and/or `ftdi_product_id` as keyword args into `OpenDMXController` based on the device you are using, if the defaults aren't correct?

self.__ftdi_vendor_id = kwargs.pop("ftdi_vendor_id", 0x0403)
self.__ftdi_product_id = kwargs.pop("ftdi_product_id", 0x6001)
self.__ftdi_serial = kwargs.pop("ftdi_serial", None)

Originally posted by @MattIPv4 in #47 (comment)

Support for OLA?

Hi,

There isn't support for the Open Lighting Architecture if I see that right? I was wondering whether it would make sense
to have a controller that interfaces with OLA via their Python APIs?

I'm new to DMX and OLA but I've got a setup working with OLA and a BitWizard usb dongle (http://www.bitwizard.nl/shop/raspberry-pi?product_id=154). What I'm looking for is a QLCplus-like web interface for
managing my lights.

So I'm kinda wondering if this is the right project for me!

Cheers!

Implement effect library

  • Define effects directory structure (similar to fixtures, but type not manufacturer)
  • Create base effects class
  • Create some basic dim chase effects as templates for further effects

Consider allowing outside module names for light definitions

At present, its difficult to add light definitions without contributing directly to the project since the validate_item function assumes the PyDMXControl.profiles. module name being present. Perhaps the code could be modified si that if the module is not found you search the broader namespace for the module before failing.

I plan to hopefully contribute to this projects codebase on a few fronts after I get done with my own testing. ๐Ÿ˜„

In the meantime, I found a work around. If one defines a light in a file called MyLight with a class of MyAwesomeLight, they can add this to their executing class:

test.py

import sys
from PyDMXControl.controllers import OpenDMXController

import MyLight
sys.modules['PyDMXControl.profiles.MyLight'] = MyLight

dmx.json.load_config('light_config.json')

light_config.json

[
    {
        "type": "MyLight.MyAwesomeLight",
        "args": [],
        "name": "Light 1",
        "start_channel": 1
    },
    {
        "type": "MyLight.MyAwesomeLight",
        "args": [],
        "name": "Light 2",
        "start_channel": 8
    }
]

Web API

Possibly look into providing a basic web api that enables fixture control (possibly effects etc too?) via web requests

[Python] Load fixtures from a JSON file

Ability to load a set of fixtures from a JSON file and instantiate them all in the controller.

Additionally, the ability to save a current fixture set from the controller to a JSON file.

Fresh install, "No backend available" on OpenDMXController() instantiation

Follows the instructions, pip installed via pip install -U PyDMXControl.

Tried to run the example code, but when I run dmx = OpenDMXController() I get the following exception:

>>> dmx = OpenDMXController()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "C:\Python310\lib\site-packages\PyDMXControl\controllers\_OpenDMXController.py", line 27, in __init__
    super().__init__(*args, **kwargs)
  File "C:\Python310\lib\site-packages\PyDMXControl\controllers\_TransmittingController.py", line 34, in __init__
    self.run()
  File "C:\Python310\lib\site-packages\PyDMXControl\controllers\_TransmittingController.py", line 92, in run
    self._connect()
  File "C:\Python310\lib\site-packages\PyDMXControl\controllers\_OpenDMXController.py", line 39, in _connect
    self.__ftdi.open(self.__ftdi_vendor_id, self.__ftdi_product_id, serial=self.__ftdi_serial)
  File "C:\Python310\lib\site-packages\pyftdi\ftdi.py", line 527, in open
    device = UsbTools.get_device(devdesc)
  File "C:\Python310\lib\site-packages\pyftdi\usbtools.py", line 175, in get_device
    devs = cls._find_devices(devdesc.vid, devdesc.pid)
  File "C:\Python310\lib\site-packages\pyftdi\usbtools.py", line 597, in _find_devices
    backend = cls._load_backend()
  File "C:\Python310\lib\site-packages\pyftdi\usbtools.py", line 663, in _load_backend
    raise ValueError('No backend available')
ValueError: No backend available

Running Windows 11, Python 3.10

trying to get the basic install to work

after typing initial install, first of list of errors appears.
file usr/share/python-wheels/urllib3-1.19.1-py2.py3-none-any.whl/urllib3/connection.py,
line 138 in _new_conn
??

Cannot import 'OpenDMXController'

Hi,

I am trying to get started with DMX via python. After installing the package I seem to be missing some files.

using from PyDMXControl.controllers import OpenDMXController exits with
ImportError: cannot import name 'OpenDMXController' from 'PyDMXControl.controllers' (/home/pi/startup/env/lib/python3.9/site-packages/PyDMXControl/controllers/__init__.py)

Do I have to install the package in a specific location?

[Python] Command line / argument parsing (from a string)

Drop the terminal debug system and replace with a command line for control.
Command line should be in its own sub package so that it can be used in both a terminal debug mode and via the web debug control in #5
The command line should support access of global callbacks, fixture helpers, fixture colors and individual fixture channels.
Additionally, support for selecting groups of fixtures and then using fixture helpers/colors/channels would be a plus.

Cannot install

Hi

I am trying to install it on a Raspberry 3B+ and get the folllowing errors. Is it something I do wrong or is there an error in the script?

---

pi@zraspi:~ $ pip install PyDMXControl
Looking in indexes: https://pypi.org/simple, https://www.piwheels.org/simple
Collecting PyDMXControl
Could not find a version that satisfies the requirement PyDMXControl (from versions: )
No matching distribution found for PyDMXControl

---

pi@zraspi:~ $ pip install -U git+https://github.com/MattIPv4/PyDMXControl#egg=PyDMXControl[audio]
Looking in indexes: https://pypi.org/simple, https://www.piwheels.org/simple
Collecting PyDMXControl[audio] from git+https://github.com/MattIPv4/PyDMXControl#egg=PyDMXControl[audio]
Cloning https://github.com/MattIPv4/PyDMXControl to /tmp/pip-install-a3zRZy/PyDMXControl
Complete output from command python setup.py egg_info:
Traceback (most recent call last):
File "", line 1, in
File "/tmp/pip-install-a3zRZy/PyDMXControl/setup.py", line 27
def fetch_reqs(base: str = "") -> List[str]:
^
SyntaxError: invalid syntax

----------------------------------------

Command "python setup.py egg_info" failed with error code 1 in /tmp/pip-install-a3zRZy/PyDMXControl/

Multiple USB to DMX interface support?

Hi Matt! Iโ€˜m currently trying to use this library for a lighting project. I use USB to DMX interface cables with FT232R chip. I used "zadig" to flash the driver of interface to libusb-win32 and successfully dim the light on PC using Python! Thankyou :)

But I found when I plug two dongles in my PC, it seems that it can only control one of them. Luminaires of the other cable won't work.
Does this library support multiple interface to work simultaneously?

I am not a programmer. If I question something wrong please forgive me. And here's my code:


# Create controller
dmx = Controller()

# Load fixture from JSON
dmx.json.load_config('LabLight.json')

# Define a global fade time
fade_time = 5000

# DMA Value Mapping Percentage
def percent_to_dmx_value(percent):
    return int((255 * percent) / 100)

# clear
dmx.clear_all_effects()

for brightness_percent in range(5, 101, 5):
    dmx_value = percent_to_dmx_value(brightness_percent)
    # Dimming
    for f in dmx.get_fixtures_by_name_include('DownLight_1Y'):       # Y for Yellow light, W for White light
        f.dim(dmx_value, fade_time)
    for f in dmx.get_fixtures_by_name_include('DownLight_1W'):
        f.dim(dmx_value, fade_time)
    for f in dmx.get_fixtures_by_name_include('DownLight_2Y'):
        f.dim(dmx_value, fade_time)
    for f in dmx.get_fixtures_by_name_include('DownLight_2W'):
        f.dim(dmx_value, fade_time)
    # rest of downlights

    time.sleep(3)

# Manual Close
dmx.sleep_till_enter()
dmx.close()

And the json:

    {
        "type": "Generic.Dimmer",
        "args": [],
        "name": "DownLight_1Y",
        "start_channel": 1
    },
    {
        "type": "Generic.Dimmer",
        "args": [],
        "name": "DownLight_1W",
        "start_channel": 2
    },
    {
        "type": "Generic.Dimmer",
        "args": [],
        "name": "DownLight_2Y",
        "start_channel": 3
    },
    {
        "type": "Generic.Dimmer",
        "args": [],
        "name": "DownLight_2W",
        "start_channel": 4
    },
    {
        "type": "Generic.Dimmer",
        "args": [],
        "name": "DownLight_3Y",
        "start_channel": 5
    },
    {
        "type": "Generic.Dimmer",
        "args": [],
        "name": "DownLight_3W",
        "start_channel": 6
    }
]```

There're more but it's just for example.

For instance Downlight1-3 connect dongle_1, and 3_6 connect dongle_2. 

[JavaScript] Swipe to go back (web debug control panel)

The web debug control panel, when used as a web app on iOS does not have the ability to swipe to go back.
Swipe to go back should be implemented on the fixture and channel control pages to navigate up the page structure (fixture to home, channel to fixture).
This should ideally be done using vanilla JS as jQuery or similar are not currently in use on the site and I would like to keep it that way.

No backend available

Hello, just install from pip with python 3.11.1 and i got an error when i try to use PyDMXController.

image

Can you help me ? I wan't use this lib for a xmas project, i'm afraid about time if I keep blocked.

Thanks by advance for your help !

[Python] Implement docstrings and testing

Currently the library has a lot of code dumped throughout that has no documentation associated to explain what it does. Additionally, there is no real testing in place to ensure older methods are not broken by never changes etc.

Therefor, implementing correct docstrings throughout the code and implementing proper testing would be a good way to bring up the quality of the library.

TypeError in web/_routes.py

web/_routes.py contains Colors.to_hex(this_fixture.get_color()) a few times, and there's no type known for this_fixture (in pyright, at least).

If that type were annotated, you'd get an early warning that get_color() can return None, but to_hex can't take None.

All 512 channels being sent every transmission causes slow down.

Thank you for this very helpful library!
I came across an issue with my uDMX device when trying to fade colours, the transition was very jerky. I found that uDMXController._transmit() was only sending data at about 6 times per second, this seems surprisingly slow.

I was able to speed this up significantly (to about 30Hz) by changing:
self.__udmx.send_multi_value(first, frame)
to
self.__udmx.send_multi_value(first, frame[0:8])
As far as I understand, frame contains all 512 channels and these are all sent every update, causing a significant delay. Instead sending only 8 channels massively sped up the response.

I was wondering if there is some way to reduce the size of frame depending on the number of fixtures the user needs, or only transmit the channels that have changed since the last transmission?

A simple example script doesn't work with FT232 USB dongle

I have a DMX512 decoder with LEDs at address 1. It is connected to the PC via USB/RS485 dongle using FT232R chip. It works fine with QLC+ app, but this PyDMXControl script:

from PyDMXControl.controllers import SerialController
from PyDMXControl.profiles.Generic import Dimmer

dmx = SerialController('/dev/ttyUSB0')
leds = dmx.add_fixture(Dimmer, name='LEDs')
leds.dim(127, 5000)

has no effect. I also tried:

from PyDMXControl.controllers import SerialController

dmx = SerialController('/dev/ttyUSB0')
dmx.all_on()

and no effect again. Can someone help me with a basic on/off control of one or more channels using the hardware I have?

[JavaScript] Mobile color picker

The current color picker on the web control panel makes use of the HTML5 color picker input which isn't support on most mobile devices.

I would like to have a color picker implemented on the fixture control page that supports mobile.
Further, the color picker should update the fixture color as the picker is selected (before mouse/finger release, before submit etc).
Additionally, the picker should still allow users to type in their own custom hex value character by character.

Preferably, this should not use jQuery as the site currently does not use it.

Flicker when using SerialController on Linux/rPi

Hi,
Love the library so far, thanks!
I've been using a SerialController and a cheap USB to DMX converter to operate a small pinspot light. The following code works as expected on windows:

from PyDMXControl.controllers import SerialController
from PyDMXControl.profiles.Generic import Dimmer
dmx = SerialController('COM3') #or '/dev/ttyUSB0'
ps1= dmx.add_fixture(Dimmer, name="PinSpot1")
ps1.dim(127, 5000)

However, the same code on raspberry pi produces a correct dim sequence, but with a flicker at about 2hz.
Any idea why that might be the case?

val in self.channels.items() can be float

Hi fellow,

thanks a looot for your library. Real nice work.

I ran into an issue (can't tell you the origin), but by using a constant stream following line in _Controller.py might create a float, which later on will crash the program:

# Get all channels values
               for key, val in self.channels.items():
                    # If channel in frame
                    if key - first < len(self.__frame):
                       self.__frame[key - first] = int(val[0])`

i placed an int() around the val[0]. Not sure if that's in general a good idea.

but it fixed the issue, that otherwise at this call would break the runtime.

def _transmit(self, frame: List[int], first: int):
        # Convert to a bytearray and pad the start of the frame
        # We're transmitting direct DMX data here, so a frame must start at channel 1, but can end early
        try:
            data = bytearray(([0] * (first - 1)) + frame)
            # The first byte in the type, and is `0` for normal DMX data
            data.insert(0, 0)

            # Write
            self.__device.send_break(100e-6)
            sleep(10e-6)
            self.__device.write(data)
        except:
            print("bad request")`
```

as you see I made a try / except for myself.

Discussion: Architectural Considerations for Live Band Lighting Controller

Publishing this as more of a discussion item for @MattIPv4 to consider and perhaps comment on rather than an actual enhancement request appropriate for this library. A lot of what I've run into in my work might end up being breaking changes if actually tackled as an enhancement to this library. I'm considering branching off of this project to do some of these enhancements but before doing so wanted to outline my thinking.

โ„น๏ธ Background: I'm attempting to use PyDMXControl as the underlying library of a Midi controllable show controller for live bands that speaks DMX and will control multiple fixtures based on preprogrammed patterns. In doing so, I've come across some edge cases that possibly rub up against some core design assumptions of PyDMXControl.

Clarify and Align speed, offset, and delay parameters

I noticed that speed is in ms while offset and delay are in percentage integers (i.e. 50 = 50%). Took me a while to work out the math to figure out what was going on here. It might be helpful to those using this in precise timing applications to keep these consistent as ms.

Proposed Sequence Effect Class

I had the need to be able to kick off a string of animations targeted towards a group of fixtures but then also loopback to a specific step. Consider the example of a scene change that bursts the lights to full white then begins cycling a chase-like pattern through 4-5 steps.

To implement this, I created a new Sequence Effect class that allows one to pass in a list of Fixture operations that you'd like to perform at certain times in sequence with ability to loopback to a specific index and define the step timing. Steps are passed in a dict of tuples where the key is the ms value at which to perform the animation and the tuple contains the Fixture operation, and arguments. You can also offset by step instead of percentage, and define a loopback point in that list of steps.

The following will run all lights Pink, Blue, Red, Warm, Green, then cycle Red, Warm, Green in a loop. Because offset_index is False, all lights are in sync. If offset_index was True, then the first light in the all_lights list would start on pink, the second would start on Blue, the third on Red, etc.

all_alights = dmx.get_fixtures_by_name_include('Band')
Sequence.group_apply(all_alights, offset_by_index=False, loopback_index=2, steps={
    0: [["color",Colors.Pink,0]],
    1000: [["color",Colors.Blue,500]],
    2000: [["color",Colors.Red,500]],
    3000: [["color",Colors.Warm,500]],
    4000: [["color",Colors.Green,500]]
})

Proposed Ability to Cancel Fixture Animations

Considering in my code I now have this Sequence class that can apply animations across fixtures, if I want to enable a new Sequence, I need the ability to not only remove the Effect from the callbacks (e.g. my specific Sequence class), but also the animation calls that were attached to the fixtures. I encountered this when applying this use case:

Let's say I have a Sequence that slowly fades out all lights over a period of 8000ms followed by bringing those lights up to half dim in 5000ms. (good for end of song and then bringing house lights backup before next song ๐Ÿ˜Ž)

Before that first fade out is completed, let's say my Light Controller responds to a Midi input 4000ms into that Sequence that requests a new sequence be executed instead. To handle this I can remove the callback that refers to my Sequence which would prevent the second half dim 5000ms call from being executed.

However, the previously executed call to the Fixtures that is still running "color" or "dim" over the initial 8000ms is running and cannot be stopped.

Removing all callbacks at the controller level is a no-go because the __send function that transmits values to DMX is part of that group.

Still considering the best way to handle this. I've had success clearing all callbacks and then adding back the__send callback, but it seems hackish. Still pondering and experimenting. ๐Ÿค”

dmx.clear_all_effects()
dmx.ticker.clear_callbacks()
dmx.ticker.add_callback(dmx._TransmittingController__send, 0)

At any rate, you can probably see that my use is running into some possible design assumptions. I'd be happy to consider thoughts and opinions on this. I would love to contribute to this project and its functionality rather than creating a Frankensteined branch.

Thanks for listening.

Lock down requirements.txt to specific versions

Running the sample example from a fresh install on Python 3.9 gives the following error:

Traceback (most recent call last):
  File "/home/show/showcontroller/tests/test_1.py", line 3, in <module>
    from PyDMXControl.controllers import OpenDMXController
  File "/home/show/showcontroller/scenv/lib/python3.9/site-packages/PyDMXControl/controllers/__init__.py", line 20, in <module>
    from ._Controller import Controller
  File "/home/show/showcontroller/scenv/lib/python3.9/site-packages/PyDMXControl/controllers/_Controller.py", line 20, in <module>
    from ..web import WebController
  File "/home/show/showcontroller/scenv/lib/python3.9/site-packages/PyDMXControl/web/__init__.py", line 20, in <module>
    from ._webController import WebController
  File "/home/show/showcontroller/scenv/lib/python3.9/site-packages/PyDMXControl/web/_webController.py", line 16, in <module>
    from ._routes import routes  # Web Routes
  File "/home/show/showcontroller/scenv/lib/python3.9/site-packages/PyDMXControl/web/_routes.py", line 17, in <module>
    routes = Blueprint('', __name__, url_prefix='/')
  File "/home/show/showcontroller/scenv/lib/python3.9/site-packages/flask/blueprints.py", line 196, in __init__
    raise ValueError("'name' may not be empty.")
ValueError: 'name' may not be empty.

A breaking change in Flask 2.3 is responsible. Due to this you may want to lock down your requirements.txt to specific versions to prevent this in the future.

See #45

Custom Channels

Thank you for this great project, really cool!
I'd like to add some more channels because I got a RGB LED bar that contains 16 segments (R, G, B for each segment, thus 48 channels).
What would be the best way for me to modify the Controller file to support more than the default colors and 'dim' and so on?
Hardcoed channel numbers wouldn't be a problem for me, plus I don't need the web interface because I'm trying to realize a sound-to-light script.

error: no usb devices opened

getting this error

In [8]: from PyDMXControl.controllers import uDMXController
   ...:

In [9]: dmx = uDMXController()

Exception in thread Thread-1088:
Traceback (most recent call last):
  File "/usr/lib/python3.6/threading.py", line 916, in _bootstrap_inner
    self.run()
  File "/usr/lib/python3.6/threading.py", line 864, in run
    self._target(*self._args, **self._kwargs)
  File "/home/rjosyula/.dirty/raj/lib/python3.6/site-packages/PyDMXControl/utils/timing/_Ticker.py", line 56, in __ticker__loop
    self.__ticker()
  File "/home/rjosyula/.dirty/raj/lib/python3.6/site-packages/PyDMXControl/utils/timing/_Ticker.py", line 42, in __ticker
    callback()
  File "/home/rjosyula/.dirty/raj/lib/python3.6/site-packages/PyDMXControl/controllers/_uDMXController.py", line 61, in _send_data
    raise e
  File "/home/rjosyula/.dirty/raj/lib/python3.6/site-packages/PyDMXControl/controllers/_uDMXController.py", line 56, in _send_data
    self.__udmx.send_multi_value(1, data)
  File "/home/rjosyula/.dirty/raj/lib/python3.6/site-packages/pyudmx/pyudmx.py", line 149, in send_multi_value
    channel=channel, data_or_length=ba)
  File "/home/rjosyula/.dirty/raj/lib/python3.6/site-packages/pyudmx/pyudmx.py", line 94, in _send_control_message
    raise ValueError("No usb device opened")
ValueError: No usb device opened

In [10]:

"ValueError: 'name' may not be empty." when Flask 2.3.x installed

Flask appears to have made a change in the 2.3.x series that the name of a Blueprint cannot be the empty string.

For example, with Flask 2.3.2 installed, importing

from PyDMXControl.controllers import OpenDMXController

results in the exception:

File "C:\Users\ASC\Documents\constellation-dev\build\apps\venv_3_11\Lib\site-packages\PyDMXControl\web\_routes.py", line 17, in <module>
    routes = Blueprint('', __name__, url_prefix='/')
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\ASC\Documents\constellation-dev\build\apps\venv_3_11\Lib\site-packages\flask\blueprints.py", line 196, in __init__
    raise ValueError("'name' may not be empty.")
ValueError: 'name' may not be empty.

I have verified this in Windows and macOS. Forcing the install of Flask 2.2.4 resolves this problem. The fix should be as easy as replacing '' with any value.

LTP needs to be implemented

Currently LTP is implemented as lowest. No one does/uses this. Needs to be implemented as latest.

Thoughts on implementing this: each channel should be an instance of a channel class. This class contains the name, aliases, value (and whatever else it needs) as well as the time it was last updated at. The controller can then use this as needed to implement LTP.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.