DMX lighting

Hello @Breina any plan to work on this topic ? Linear dimming is just the worst thing to do in most cases:

  • actual visual brightness changes drastically for smaller changes in lower % range (e.g. 10% → 20%)
  • changes barely for larger changes in upper % range (e.g. 60% → 100%)

Many credits for your great integration, is working perfectly, just missing the possibility to use other output corrections …

I will definitely fix this, but my current focus is on fixing these ones;

More people are waiting on this one, and it has been in the works for a while. Since this is a major overhaul, I don’t want to change the existing code too much, to avoid conflicts.

3 Likes

@Breina - thanks for the feedback, and understand your position. Good luck 1st with the major overhaul !

@turboPasqual - FYI: I applied your suggested code change in light.py but that did not result in the desired behavior … dimming was still linear however output correction quadratic defined for both universe and channels …

Hi @robinbervoets .

Thank you for trying my code change.

Did you change both occurences of “output_correction” to “set_output_correction”?
Additionally I think you need to restart home assistant after changing the code.

For me that had worked very well. Unfortunately this was not good enough for me. My DMX controllers already offer a “logarithmic” dimming curve which works better for me than the available dimming curves in this integration. Quadratic is still too steep and cubic/quadruple won’t switch on the light at all until I dim to a certain level (I think it was around 10%).

Maybe there will be an option in the future to implement individual dimming curves other than those that python already has.
By crawling the internet and finding 2 home assistant scripts I was able to gather a few dimming functions. Maybe those are of any help in the future.

Link to the scripts:
https://community.home-assistant.io/t/light-fader-with-curves-linear-exponential-and-smooth/366157
https://community.home-assistant.io/t/ashley-s-light-fader-2-0-fade-lights-and-or-color-temperature-with-your-choice-of-easing-curves-including-ease-in-ease-out-and-ease-in-out/584077

The formulas of some dimming curves:
(x = input value, a = total number of values [typically 256 or 65536])

name function
linear y = x
logarithmic y = 2^(log2(a-1) * (x+1) / a)
quadratic y = (x / (a-1)) ^ 2 * (a-1)
cubic y = (x / (a-1)) ^ 3 * (a-1)
quadruple y = (x / (a-1)) ^ 4 * (a-1)
exp2 y = (((((a^(1/2))-1) / (a-1)) * x + 1) ^ 2) - 1
exp5 y = (((((a^(1/5))-1) / (a-1)) * x + 1) ^ 5) - 1
smooth y = a ^ (x / (a -1)) - 1
1 Like

Hi, everyone:
I’d like to chime in that just about all LED’d have a very non-linear response at the low end of the brightness and some also at the high end of brightness, that can’t fit into any one clean formula (unless it’s absurdly complex). Dimmers may have an impact as well, in that certain bulbs with certain dimmers may buzz, hiss, or flicker at the low end (or sometimes with lower-end hardware also near a 50% point).

I propose the following scheme of mapping the user’s intent (% illumination demand level) to the fixture’s performance, where P is the raw / native / uncorrected dimmer output in % and L is the actual light output in %. This is a finite list of 5 or 6 points that would profile a given type LED in a given type fixture:

  • P0: Highest P where L is still 0
  • P0.4: P where L is 0.4%; this would be the lowest flicker-free output from a fixture. 0.4% and not 0.5% as 0.004 is roughly 1/255
  • P1: P where L is 1%;
  • P10: P where L is 10%;
  • P40: P where L is 40%;
  • P90: P where L is 90% (optional);

The method of interpolation between these points is as you see fit. Because the light profile points are exact, whatever’s computationally simplest that’s one notch better than linear interpolation, I think can be good enough.

It’d be also perfectly fine to denominate these in units from 0 to 255 vs 0 to 100%, at equivalent brightness points. Either way, the thrust of my message in a nutshell is that:

  1. The main objective is for the fixture to produce light in the 1-100% user input brightness range (or 1-255), i.e. map away the region where he fixture doesn’t light up.
  2. The secondary objective is to “tame” to the extent possible the low end of the curve (that is highly peculiar to each LED model) such that useful low brightness levels can be selected - vs going from 1% to 2% input making LED jump straight to 20% of its light output.
  3. The final objective is to facilitate brightness curve matching across different lights.

I’m quite convinced that NO choice of “pure” math functions where 0 maps to 0, can do it adequately. However profiling the light output starting point, a few low values biased towards the very start of light output, and one middle and one high value, can profile different lights to a point where pretty consistent output across them can be achieved with 5 or 6 data points.

There can be a global “brightness curve” setting on top of these already calibrated profiles. It should be a single number, akin to “gamma” in displays or photo editing, to be able to globally adjust the “middle bulge” of the brightness scale. The further from 1.0, the more distinct input brightness % levels would be assigned to the lower end of the scale of their light control sliders. (Although I feel this global curve ultimately ought to be more of a HA global light preference and HA already offers an entity mapping integration that can do one-value mapping.)

@turboPasqual I’m the author of Ashley’s Light Fader (which you had also linked to), and if it might be helpful to anyone here, the formulas for the curves that I’m using are all freely available at easings.net:

In each of the formulas below, x represents the current linear percentage of the fade that has been completed, as a value from 0.0 to 1.0. And then what’s returned is a number—also from 0.0 to 1.0—that represents the current percentage after that particular curve has been applied.

Sine

Quad

Cubic

Quart

2 Likes

Hi, just to be lazy I wondered if you might share how you’re setting up and programming your moving head lights? I have to unexpectedly integrate some next week and hoping I can cut out the experiment-and-swear middle ground if possible!!

Good day All

I am trying to get DMX lighting installed and configured in HA. I have the configuration.yaml setup and compiled with no startup errors I just don’t know where to put the rest of the files for DMX Artnet . My apologies for the noob questions Just need pointed in the right direction and I can’t find anything remotely close on the web, and the README instructions only talk about the configuration.yaml would someone mind showing me what needs to be configured, besides the configuration.yaml

The Rest of the files are under the custom components and I am not sure how to organize them in File editor.

My DMX Setup:

  1. ENTTEC - S-Play Mini with 1 DMX Universe Art-Net enabled ( Universes 1 ) ( IP 192.168.55.x
  2. ENTTEC - Ethergate DIN 2 DMX Universes Art-Net enabled ( Universes 3 & 5 ) 192.168.55.x
  3. LED Strips with CH1 thru CH492 in use LED’s are RGBW ( Universes 1 )
  4. LED Strip with CH1 thru CH328 in use LED’s are RGBW ( Universes 2 )
  5. LED Strip with CH1 thru CH100 in use LED’s are RGBW ( Universes 3 )
  6. LED Strip with CH101 thru CH346 in use LED’s are GRB ( Universes 3 )

thank you in advance for any help.

All the best,

I set up a parcan at channel 1, which works, and I’m now trying to set up a moving head light that I’ve set to be channel 6. It’s got 12 channels doing various things - is the below a sensible way of addressing these?
EDIT: this just worked, no universes…
using pknight artnet dmx adapter and a beamz cobra 100h for anyone trying the same…

Also, does anyone have any scene examples for light controls using this?

devices:
          - channel: 1
            name: my_rgb_lamp
            type: rgbw
            transition: 1
            channel_size: 8bit
            output_correction: quadratic
            channel_setup:
              - r
              - g
              - b
              - W
          - channel: 6
            name: moving_head_pan
            type: dimmer
          - channel: 8
            name: moving_head_tilt
            type: dimmer
          - channel: 11
            name: moving_head_dimmer
            type: dimmer
          - channel: 13
            name: moving_head_colour
            type: dimmer
          - channel: 14
            name: moving_head_gobo
            type: dimmer

Do you happen to have any working NodeRed modules? I’ve tried the sACN ones and the Artnet one. But they’re either 5 or 8 years old and abandoned and I can’t get them to work any more. Or the ArtNet module (which is newer) just crashes the whole Node-Red.

I had hoped I can use this project, since it claims input support in some release note. And it’s not a 1 GB RAM Java beast that I have to run in addition to all the other addons on my Home Assistant…

Hi @turboPasqual, sorry for the late response, I have been out a while due to circumstances …
I still have to come back to my previous feedback: your proposed code change was working. In a 2nd observation I did monitor the actual DMX buffer on my Enttec DIN Ethergate, instead of the DMX value of the standard light entity in HA, and here the values were matching a quadratic or cubic behavior (and differing from the DMX value visible in HA, for some reason the correct value is not displayed here, still matching linear behavior).

However, as you also stated in later posts, I noticed during testing that these curves are not the way to go :slight_smile: At that time I also remembered playing around a couple of years ago with different curves (parabolic, exponent and logarithmic) in combination with limiting the “working area”, as also proposed by @Chef-de-IT. This ended up with exponent curves giving very good results. To my opinion preventing a part of the working area by defining a Min and Max DMX value in between which the 0-100% dimming should take place, is at least even important as the curve defining relation between input % and output %

** copy from Siemens TIA Portal SCL code → driving Beckhoff KL2751 dimming module **

** exponent curve → I believe n=2 gave the best results, but might vary between bulbs and dimmer? **

// uitgang scaling y=ax^n*
*  #n := #settings."dimmen uitgang scaling";*
*  #a := (100 / (100 ** #n));*
*  #x := #status."licht_waarde (%)";*
*  #y := #a * (#x ** #n);*

** and then to my opinion the most important part → defining the dimmer output working area **

// overall Licht_waarde (%)*
*  #y := #settings."min (%)" + ((#settings."max (%)" - #settings."min (%)") * #y / 100);*

@Breina when you work on the curve part I highly suggest:

  1. Add also the possibility to define DMX Min and Max values as proposed

  2. Forget about cubic and quadruple curve, but give the option to use exponent with “n” to chose.
    @all I know you have been proposing other curves but maybe we are making things too complex resulting @Breina doesnt’t know how to move forward and getting demotivated … I propose to take it step by step, so let’s start with this one which is quite straight forward and take it from there :slight_smile:

@turboPasqual @Chef-de-IT please share your thoughts

1 Like

@robinbervoets Robin, having thought about your response some more, and others, and based on my hospitality experience, I’ve this to say: broadly, we’ve 3 “stages” of light calibration. In priority order as I see it:

  1. Profiling a bare fixture’s valid dimmer input and light output levels i.e. just defining the ranges where useful & safe light output is produced at all. In practical terms (most inclusive scenario I can think of - which I have seen in the field):
    .
    1.1 A dimmer or fixture may hiss or buzz badly in say the 0-5% dim level (electrical input). A fixture doesn’t light up at all in the 0-3% dim level. It lights up at say 3.1% dim level (lighting up at 7% of its max lumen output level) but besides hissing is also flickering. The flickering goes away at 6% dim (electric input) level, at which point the bulb is producing 11% of its max lumen output level.
    .
    1.1.1 In HA, I believe the proper representation would be, 0% on HA slider is 0 dim level (duh) and 0 lumen output level. Not sure if HA supports “disallowed” ranges on a slider, but if so, the next selectable % brightness level on the HA slider should be, in this fixture’s case, 11%. With the integration knowing that for this fixture, that 11% output maps to 6% electric input, so when user picks 11% the fixture gets that 6% dimmer input.
    .
    1.1.2 If no “disallowed” ranges are supported currently, then the integration should “split the bad range down the middle”: in this case for 0-5% user or scene/script brightness demand, it should just use 0 dim input level for the given fixture, and for 6-11% brightness demand, it should just use 6% dim input level that produces that lowest buzz/hiss/flicker free lowest available output from the dimmer+bare bulb/fixture. I feel, this “starting brightness point” handling is the most important in profiling a given fixture. If we just go linear or exponential per Robin, from there to 100% and do nothing else, we’ll already have solved like 70% of the problem with that singe calibration point.
    .
    1.2 Some lights can have an intermediate brightness flicker zone say 48-52% dimmer input, which may also be sensible to be able to exclude. But this is lower priority vs point 1.3 - and getting lower all the time as LED driver quality and sophistication improves.
    .
    1.3 De-rating per-light or light type where needed. Some fixtures or dimmers can be heat or wattage or bulb life (27ft ceiling, $400 labor to swap bulb) or otherwise constrained, where say above 82% dimmer input, things start melting or smelling or the curtain touching the fixture begins to smoke or the dimmer paddle looks like something out of a Dali painting. I’ve seen and smelled it all. In this example’s case it’d be great to make “real” 82% input the “de-facto” 100% for this given fixture or fixture type, i.e. max allowed dimmer input level (say corresponding to 92% lumen output level) so when the user or scene or script pick 100% for this light, 82% input is sent instead by this integration to the respective dimmer hardware, telling the user “this is the 100% you got, bud”. I’m sure on some other planet this is resolved between a conscientious manufacturer, a conscientious electrician, and a fully informed client with budget to buy good stuff and hire smart folks. Our planet, however, has unanimously been called “Dirt” for a reason.
    .
    The peculiarity in this case is, unlike the starting point 1.1.1 where the starting range of 1-11% is genuinely blocked off or split, I think in the case of the max point 1.3 (for particular lights/dimmers that need this de-rating) we ideally want to re-scale the range so the 100% from HA’s perspective is in fact 82% input internally in the integration.
    .

  2. Profiling curve. Our eye perceives brightness logarithmically - even more so than sound. For something to seem 10x brighter vs an already fairly bright object, it needs to “really” be like 400 times as bright in linear terms. So @robinbervoets very validly picked the exponential function to “moderate” / linearize the logarithmic human perception range. This is where a coefficient can be picked per fixture, helping to match different fixtures among each other. It’s absolutely vital that this curve is passing through the “actual initial good brightness point” as defined in 1.1.1 and ends in “de-facto 100%” point 1.3. I.e. the point defined in 1.1.1 should NOT be just slung over to become “the new (0,0)” as far as this curve is concerned - or else the entire early half of the curve is going to be way off. The point defined in 1.3, however, should be slung over to become “the new (100%,100%)”.
    .

  3. Optional. And should probably be an HA-wide feature - not this one integration’s. A user (as is often the case in hospitality) may want a larger chunk of the 0-100% brightness scale be allocated to picking among the multiple dim values more precisely. So this ought to be an HA-global property.
    .

  4. Separately, certain lights’ placement or treatment (like lamp shade) may also affect their “perceived” curve “as installed” as opposed to “bare”. Like an up-shining awning light in my experience. This can also be dependent on an ambient natural light level or “competing lights” level. This is admittedly pretty advanced and I’m not aware of any light control system that accounts for this. It’s somewhat synonymous to “volume-dependent equalization” in high end speaker management systems. Just brain-dumping it here for completeness.

Cheers!

I’ve been slowly tinkering away on getting this integration compatible with more than just lights. I’m finally starting to get somewhere! :slight_smile:

So I’ve been using open-fixture-format to describe the lights, which will replace manually defining the channels yourself. This is much more powerful, with templating and switching channels.

As an example, we can grab the ligt configuration from here: cameo Hydrabeam 300 RGBW DMX fixture definition – Open Fixture Library

Then you’d only need minimal config;

image

And then the integration can the rest:


Still lots more work to do, but I feel I’m starting to get there, and wanted to share. :slight_smile:

4 Likes

Neat! The open-fixture-format looks like a a tremendous advance.

I noted that the 42-channel mode of the Hydrabeam has coarse and fine settings for things like Panning. I can’t be sure however from the HA screenshots however if the sliders adjust 16 bit values when a 16 bit capability is defined. Is that in the prototype code?

I’m starting to deploy D5-E DMX decoders for some lighting that needs 16 bit granularity. These are five LED channel decoders that take up five DMX addresses when in 8 bit mode and ten addresses when in 16 bit mode. As Chef-de-IT noted way back in May, the channel_size setting is different than PyArtNets channel width and byte_size concepts. As I understand it, the D5-E (in 16 bit mode), would have a PyArtNet channel width of 10 and a byte_size of 2. I don’t see any way to encode this in the released Art-net Lighting for DMX HACS integration.

If the prototype is intended support what I’m trying to do I’ll give it a shot.

As an aside, I was pleased to see so many going “all in” on DMX home lighting. I’m doing the same, but am using PoE for power and ArtNet for control of many of the fixtures, like the recessed circular lights and LED strips. Having a separate ArtNet IP for each group of fixtures (such as the lights in a single hallway) seems a bit over the top, but I’ll see how it works.

I have a dozen or so 2’x2’ RGBW flat panels that are pure DMX with separate Mean Well supplies since one DMX cable and one Romex cable can support several of these panels .

All of my wall switches are going to be PoE as well, so with only one or two exceptions, none of the switches will be having 120Vac going through them.

Yes, that’s implemented in this prototype! I utilise the full feature set of that open-fixture-format has to offer.

As I understand it, the D5-E (in 16 bit mode), would have a PyArtNet channel width of 10 and a byte_size of 2. I don’t see any way to encode this in the released Art-net Lighting for DMX HACS integration.

No, in the current release that would be a channel width of 5 (= 5 light outputs) with a byte_size of 2. But channel-width is calculated in function of how many channels you define, so a type rgbww would have a width of 5.

Chef-de-IT’s comment is valid, but mostly semantic. It’s still possible, but we chose bad words to describe what we meant.

The first thing I tried in HA was this:

          - channel: 45
            name: Panel 12
            type: rgbww
            channel_size: 16bit

But the result was not what I’d hoped for. When I looked at the entity state I got this:

dmx_channels: 45, 46, 47, 48, 49
dmx_values: 24576, 26624, 0, 47616, 47616
values: 132, 143, 0, 255, 255, 3824
bright: 186

It’s confusing. The dmx_values seem to be 16 bits, but ony five dmx_channels are assigned. DMX defines what’s at a single address to be only 8 bits wide so I had hoped to see dmx_channels from 45-54 assigned.

Is there a way to properly implement the D5-E in the released integration, or should I try the experimental branch?

Diving a little deeper, risking TL;DR,

Relating dmx_values: to values: and bright: confounds me as well. Each dmx_value ~ bright: * values:, but not exactly. I tried going +/-1 on each but still not an exact match.

It also looks like the architecture of having an overall fixture brightness setting and individual settings for r, g, b, ww, cw, as defined in the custom channel assignment feature, is kind of mixed in here as well. E.g. there are six values, but only five channels.

So while Chef-dr-IT’s comments are semantic, the semantics do matter because concepts seem to be getting mixed together in ways I can’t figure out. PyArtNet has a pretty orthogonal set of definitions but the current HACS integration dosen’t seem to be. It looks like the open-fixture-format defines things in a pretty orthogonal way.

That open-fixture-format schema seems to be pretty big. Parsing that (and capturing all the semantics) must have been a huge effort! Mapping this into how HA models light colors is a whole other challenge. From the point of view of an end-user it seems to make sense, but from a lighting engineering perspective, such as how to accomodate Chef-de-IT’s environmental and subjective calibration requirements, it seems to me that a “shadow” set of HA entities would be needed to be able to control the actual fixture knobs to do calibration.

So it seems like several layers of mapping may be needed to turn an end user setting into the actual DMX 8 bit settings:

user intent → fixture capabilities → fixture standalone calibration adjustments → characteristics of the environment the fixture is used in → fixture 8 bit DMX channel settings

I’m trying to get through the first two (and the last) step right now, just for the D5-E.