Giter VIP home page Giter VIP logo

pyartnet's People

Contributors

spacemanspiff2007 avatar tschundler 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

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

pyartnet's Issues

Channel 512 can't be directly faded

universe.add_channel(start=512, width=1) cant be faded. Error in the console says "start + width <= 512".
It should be "start + width -1 <= 512".

add_fade invalid assert

seems like this line is problematic
dmx_channel.py line 91

assert 0 <= k.val_target <= 255 ** self._CHANNEL_SIZE

this does not work when using 16bit+ channels. The upper limit of fade value would be 65025 or 0xFE01 instead of the expected 0xFFFF

Value should be compared against (256 ** channel_size) - 1 instead

Callbacks

Hi there.
I really like your project. Thanks for your effort.
I'm struggling to get the callbacks to work....(may be just me being quite new to python...)
Is it possible to start an ArtNet node via a python script and then to callbacks on specific values?
I guess that this is what your callback example is meant to do but I'm not able to open a node (tried to detect it with multiple ArtNet apps) or to get any callbacks.....
`from pyartnet import ArtNetNode, DmxChannel

node = ArtNetNode('127.0.0.1')
universe = node.add_universe(1)

channel = universe.add_channel(start=1, width=3)

def cb(ch: DmxChannel):
ch.add_fade([0] if ch.get_channel_values() == [255] else [255], 1000)

def cb(ch: DmxChannel):
if ch.get_channel_values() == 255:
print('channel: full')
else:
print(str(ch.get_channel_values()))
channel.callback_value_changed = cb
`
Could you point me to where I'm doing wrong?

Cheers

When using quadratic output correction the light dims before fading

Hi,
Thanks for the great Library, I am using it to add DMX onto Home assistant, incorporating the new Color Mode and using the 16 bit for smooth dimming at low level.

When using any output_correction other than linear. When a Fade starts, it will use the corrected value to start the fade then apply the correction again so the start of the fade is a lot lower value than the previous DMX value.

step to reproduce:

set: output_correction: quadratic
set: light to brightness 128
DMX value sent to Artnet is 64 due to quadratic correction
send fade to 200
the fade will start at an input value of 64 after quadratic correction it sends a DMX value of 18 is sent on Artnet instead of 64
the light will fade up from DMX value 18 to 155

Expected behavior light should fade from DMX value 64 to 155

impact: when fading up or down from a mid brightness the light dims significantly then fades to the correct value.

I have been looking at the code to see if there is an easy way to fix it but I'm still finding my way around it. If I find a solution I will let you know.

Feedback rework

Hi,

I've done a huge rework and I'd like to get some feedback on it.

The fade task now starts automatically, the refresh task however must still be started manually.
I'm unsure if I should keep it that way or if it should be started automatically.

There is an additional channel.set_value([0]) for the channel to immediately set values without a fade.

I've also added support for sACN E1.31 and KiNet, however I can not test it so some feedback would be nice.

Output correction is now set with node.set_output_correction(func) universe.set_output_correction(func) channel.set_output_correction(func)

I'm pining a couple of contributors who either reported issues or did some tests in the past.
It would be really nice to get some feedback before I finalize everything and push to pypi
@MicahMeadows @hynekcer @Breina @corb3000 @sdegrande

Reading information

Do you have any suggestions for what I could look into to read information from a Art-Net receiver? Essentially to check the value assigned to a given channel before assigning it a new one. Thank you in advance!

Can not start new fade after all fades have finished

This is because the value __fade_running of a universe is cached and never evaluated again if all fades terminated.

A poor fix is possible in dmx_channel.py:

class DmxChannel:
    ...
    def add_fade(self, ...):
        ...
        self.__fade_running = True
        self.__universe._DmxUniverse__fade_running = True  # type: ignore[attr-defined]
        return None

but it is not nice to modify protected attributes. Maybe you add a method to restart processing in a universe.

Reproducible packet error

Hi.
I am using ESPixelStick
ESPixelStick is an open hardware and very cheap implementation of several light control protocols through ethernet(wifi)
I posted an issue on the ESPixelStick Github repo.
https://github.com/forkineye/ESPixelStick/issues/697

I don't know who is the problem. If it is this library or the ESPixelStick itself.

In my repo you can find my python script, and Wireshark reports.
https://github.com/fedekrum/DMX/

How to know where is the error coming from?

Thanks

too many files open

version used: pyartnet 1.0.1
python version: 3.9.6 via venv
error: OSError: [Errno 24] Too many open files

I get an error while executing code below. When I use add_fade instead everything runs smooth, although I do get some spikes to 255 in the ArtNet output.

https://pastebin.com/pCkGWc9x

SyntaxError: 'await' outside function

I'm kinda new to python and I'm trying to create a discord bot. this is my code:
import discord
import os
client = discord.Client()

@client.event
async def on_ready():
  print('We have logged in as {0.user}'
  .format(client))

@client.event
async def on_message(message):
  if message.author == client.user:
    return

if message.content.startswith('$hello'):
  await message.channel.send('hello')

  client.run(os.getenv('califrag'))

when I run it it keeps saying SyntaxError: 'await' outside function. I have NO IDEA what's causing, or how to fix it. Please help!

Fade to 0 not working?

When i try to fade any channel to 0 it only updates it to 0 after another channel was faded to another value (thats not 0). Setting it to any other value works as intended.

Can not turn lights off without turning anything on initially

I use a script to turn some light on but then is the state of lights undefined initially. I want to turn all lights off initially for some period of time. This is not possible until the first refresh_every period expires. I would like to write e.g. a simple script tu turn lights off with waiting a minimal time determined by universe.wait_for_fades(). I'm writing a PR with fix.

Request / question: Is RDM possible?

Is there any way to get RDM information of devices (more precise: a temperature value of led controllers)?
The only possibility I see is using openlighting and its pythonAPI.
However I was looking for a more lightweight approach with a single python-artnet library.

Please close if not possible / planned and maybe add this information.

getting a SyntaxError: 'await' outside function

I'm fairly new to Python so it may be me not understanding how to implement asyncio or async definitions but i can't get past the "read me" "usage" "fades" example, i'm getting an error:
await node.start()
^
SyntaxError: 'await' outside function

I'm using version 0.8.2 and in the artnet_node.py the start function is in a 'async def' as an executable statement as it should be so i'm not sure why it's not working.

I tried putting await node.start() in a async def and in a normal def in my script but the error stays the same

Can you explain a little more how to use/start with PyArtNet in the readme?

multiple universes using add_universe

Hi, I am trying to set up multiple universes using PyArtNet like:

universe = node.add_universe(0)
multiverse = node.add_universe(1)

however only the first universe I add seems to respond: what am I doing wrong? Thanks in advance!

Add 16bits values

Your PyArtNet is amazing, compared to some other python-artnet libs, because of those faders !
However, I need to control '16bits channels' (or rather 8bits coarse + 8bits fine). This can not be achieved with PyArtNet (as far as I can see in the code).
Could it be possibly to add such a feature ?

DMX data sent seems to be 1 byte longer than the channle width

This is the original test code:

import asyncio
from pyartnet import ArtNetNode

async def main():
    # Run this code in your async function
    node = ArtNetNode('192.168.1.93', 6454)

    # Create universe 0
    universe = node.add_universe(1)

    # Add a channel to the universe which consists of 3 values
    # Default size of a value is 8Bit (0..255) so this would fill
    # the DMX values 1..3 of the universe
    chn1 = universe.add_channel(start=1, width=3)

    # Fade channel to 255,0,0 in 5s
    # The fade will automatically run in the background
    chn1.add_fade([100,200,250], 1000)

    # this can be used to wait till the fade is complete
    await chn1

asyncio.run(main())

if __name__ == '__main__':
    pass

seems to me that it would send 3 bytes on the first 3 DMX addresses but my HW receives always 4 bytes:

DMX: Univ: 1, Seq: 6, Data(4): 14 28 32 0
DMX: Univ: 1, Seq: 7, Data(4): 18 30 3C 0
DMX: Univ: 1, Seq: 8, Data(4): 1C 38 46 0
DMX: Univ: 1, Seq: 9, Data(4): 20 40 50 0
DMX: Univ: 1, Seq: 10, Data(4): 24 48 5A 0
DMX: Univ: 1, Seq: 11, Data(4): 28 50 64 0
DMX: Univ: 1, Seq: 12, Data(4): 2C 58 6E 0
DMX: Univ: 1, Seq: 13, Data(4): 30 60 78 0
DMX: Univ: 1, Seq: 14, Data(4): 34 68 82 0
DMX: Univ: 1, Seq: 15, Data(4): 38 70 8C 0
DMX: Univ: 1, Seq: 16, Data(4): 3C 78 96 0
DMX: Univ: 1, Seq: 17, Data(4): 40 80 A0 0
DMX: Univ: 1, Seq: 18, Data(4): 44 88 AA 0
DMX: Univ: 1, Seq: 19, Data(4): 48 90 B4 0
DMX: Univ: 1, Seq: 20, Data(4): 4C 98 BE 0
DMX: Univ: 1, Seq: 21, Data(4): 50 A0 C8 0
DMX: Univ: 1, Seq: 22, Data(4): 54 A8 D2 0
DMX: Univ: 1, Seq: 23, Data(4): 58 B0 DC 0
DMX: Univ: 1, Seq: 24, Data(4): 5C B8 E6 0
DMX: Univ: 1, Seq: 25, Data(4): 60 C0 F0 0
DMX: Univ: 1, Seq: 26, Data(4): 64 C8 FA 0

Did I understand correctly the code? Seems to me there are one more byte always 0 for DMX 4th address. What do I need to send the fading values on the first 3 DMX addresses?

DMX Input

Context on my end

I'm implementing HomeAssistant as an ArtNet controller. This means it's going poll for ArtNet devices on the network and reply to other ArtNet controllers do the same. This will mean that other controllers will be able to update our state.

image

image

Code for the ArtNet server is available. I have yet to clean it up, as it's pretty messy. But it does work! :)

Current implementation on my end

I'm able to bridge my implementation to ArtNetNode (or BaseNode in the comingrelease). This just adds the logic that the server needs to start polling, opening sockets, etc... I've set it up this way so that I can keep your error correction and animations, whilst being able to expand on the functionality of ArtNet.

This is able to receive ArtDmx packets containing data on the port (net, sub_net, universe), and a bytearray of raw data. I'm able to simply override the universe's data, but omits output correction and callbacks.

Requested change on your end

  • Provide a way to update a universe's data (partially).
  • Reverse output correct the DMX data, so that the same uncorrected input values reflect in the same corrected outputs.
  • Add a callback for channels that changed, containing the new values.

Fades start from value 0, instead of fading from the existing value

When doing an channel.add_fade, the fade starts from values [0, 0], instead of transitioning from the current values.

This means that in the below example, the second fade makes the light go off first, then transitions to the actual value. A consequence is also that fading to black is always instant.

I'm not adept enough to write a unit test for it, but here's a reproduction scenario at least:

import asyncio

from src.pyartnet import ArtNetNode


async def artnet():
    node = ArtNetNode("192.168.1.15", 6454)
    universe = node.add_universe(0)
    channel = universe.add_channel(start=105, width=2, byte_size=2, byte_order='big')

    channel.add_fade([0, 65535], 1000)
    await channel

    channel.add_fade([65535, 0], 1000)
    await channel


loop = asyncio.new_event_loop()
loop.run_until_complete(artnet())

Discussion: effects

HA has the possibility of adding arbitrary effects on a per-light basis. As such:

image

I think it might be a fun feature to implement in PyArtNet, given that it's already doing the transitional animations. It has the threading infrastructure to handle this as well.

Might make more sense to do it externally though, just poking and prodding here first. :)

Feature request: A way to skip all the fading and just set pixel values

Sorry if I'm missing something, but is there any way to use this library to just say "Set these pixels to these values, immediately, and keep them that way"? As far as I can tell, my only option is to fade in my desired colors, and then have them fade out even though I don't want them to.

Feature: read universes

As a developer, I would like to read the values of every universe, so that I can match its state in my backend.

Specifically for asynchronously updating Home Assistant.

Planning to implement this myself, just being upfront. :)

How to use 'set_values' ?

Hi, i want set values for channels without fade, but it doesn't work。
fade mode works。

import asyncio
from pyartnet import ArtNetNode

async def main():
    # Run this code in your async function
    node = ArtNetNode('192.168.1.9', 6454)

    # Create universe 0
    universe = node.add_universe(8)
    channel = universe.add_channel(start=10, width=6)
    # channel.add_fade([255,0,0,0,255,0], 5000)
    channel.set_values([255,255,255,255,255,255])
  
    await channel
    # node.start_refresh()
    print('uuuuuu')
    # time.sleep(8)
    # print('uuuuuu--->')



asyncio.run(main())

No way to turn off all lights if lights are already off (e.g. after restart)

Issue: If an .add_fade commands zero for all channels, no ArtNet packet is sent over Ethernet

Workaround 1: Create a phantom channel after all other channels and send any non-zero value when zeroing all other channels. Cons - only allows for 511 DMX channels in the universe.

Workaround 2: Using a non-linear output correction and setting at least a single channel to hex value of 1 (which output correction adjusts to a value of zero) will still send the ArtNet packet.

Note, this was only tested on a single universe application.

Broadcast Artnet

Hi, whenever I try to broadcast artnet across a network it just doesn't work (target ip of 255.255.255.255). If I keyboard break I get this error:

Traceback (most recent call last):
File "shortArtnetTest.py", line 28, in
asyncio.run(main())
File "/usr/lib/python3.7/asyncio/runners.py", line 43, in run
return loop.run_until_complete(main)
File "/usr/lib/python3.7/asyncio/base_events.py", line 571, in run_until_complete
self.run_forever()
File "/usr/lib/python3.7/asyncio/base_events.py", line 539, in run_forever
self._run_once()
File "/usr/lib/python3.7/asyncio/base_events.py", line 1739, in _run_once
event_list = self._selector.select(timeout)
File "/usr/lib/python3.7/selectors.py", line 468, in select
fd_event_list = self._selector.poll(timeout, max_ev)
KeyboardInterrupt
Task exception was never retrieved
future: <Task finished coro=<ArtNetNode.__worker() done, defined at /usr/local/lib/python3.7/dist-packages/pyartnet/artnet_node.py:63> exception=PermissionError(13, 'Permission denied')>
Traceback (most recent call last):
File "/usr/local/lib/python3.7/dist-packages/pyartnet/artnet_node.py", line 76, in __worker
self.update()
File "/usr/local/lib/python3.7/dist-packages/pyartnet/artnet_node.py", line 129, in update
self._socket.sendto(packet, (self.__host, self.__port))
PermissionError: [Errno 13] Permission denied

If I target specific IPs instead of broadcast everything works fine, any help would be much appreciated!
Thanks!

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.