Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add E1.31 Support #2355

Open
wants to merge 2 commits into
base: dev
Choose a base branch
from

Conversation

CalcProgrammer1
Copy link

Implements changes requested in #1922

Adds configurable E1.31 support for controlling Espurna lighting devices with E1.31 lighting software such as Vixen 3, OpenRGB, etc. Web-based configuration page provides the ability to enable E1.31 support globally and enable E1.31 control for each lighting channel. You can set the universe for the device and the E1.31 channel for each Espurna lighting channel. Can be disabled with E131_SUPPORT flag. Requires light support.

I have addressed the comments from my first push of this branch.

Copy link
Collaborator

@mcspr mcspr left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you point to any simple client to test this out?

Comment on lines +135 to +144
_e131_light_0_enabled = getSetting("e131Light0Enabled", false);
_e131_light_0_channel = getSetting("e131Light0Channel", 1);
_e131_light_1_enabled = getSetting("e131Light1Enabled", false);
_e131_light_1_channel = getSetting("e131Light1Channel", 2);
_e131_light_2_enabled = getSetting("e131Light2Enabled", false);
_e131_light_2_channel = getSetting("e131Light2Channel", 3);
_e131_light_3_enabled = getSetting("e131Light3Enabled", false);
_e131_light_3_channel = getSetting("e131Light3Channel", 4);
_e131_light_4_enabled = getSetting("e131Light4Enabled", false);
_e131_light_4_channel = getSetting("e131Light4Channel", 5);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note of lightChannels(). Right now configuration... seems straightforward, but bulky :/
As noticed in the other comment, my92xx uses simple string to map as 1,2,3,4,5 to map espurna channel 0 to 1, channel 1 to 2 and etc. We also won't need 10 config keys at the same time. (and we need a bit different parser, as there are more channels in e131 that go above a single digit)

'no mapping' is another question?

  • 1,,3,4,5
  • 1,-,-,4,5
  • 0:1,2:2 (left of ':' is our channel, right is e131)

code/espurna/e131.cpp Outdated Show resolved Hide resolved

//* Initializing multicast mode must be done when the WiFi is connected, so
//* set a flag to track when WiFi is connected and disconnected
if (WiFi.status() == WL_CONNECTED) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Check out jw.subscribe callbacks, there is MESSAGE_CONNECTED and MESSAGE_DISCONNECTED for station events. Both happen in loop(), see wifi.cpp for example.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated to use a WiFi callback to get connection status

code/espurna/config/general.h Show resolved Hide resolved
Comment on lines +62 to +71
root["e131Light0Enabled"] = getSetting("e131Light0Enabled", false);
root["e131Light0Channel"] = getSetting("e131Light0Channel", 1);
root["e131Light1Enabled"] = getSetting("e131Light1Enabled", false);
root["e131Light1Channel"] = getSetting("e131Light1Channel", 2);
root["e131Light2Enabled"] = getSetting("e131Light2Enabled", false);
root["e131Light2Channel"] = getSetting("e131Light2Channel", 3);
root["e131Light3Enabled"] = getSetting("e131Light3Enabled", false);
root["e131Light3Channel"] = getSetting("e131Light3Channel", 4);
root["e131Light4Enabled"] = getSetting("e131Light4Enabled", false);
root["e131Light4Channel"] = getSetting("e131Light4Channel", 5);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(again about the cfg)
We also will send less keys to the WebUI.

But, it will be more complicated from the .js script side :/
Another alternative to map string is to use e131Ch# and simply loop all channels like Domoticz, Thingspeak map internal IDs to external.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it be possible to keep the same web UI and pack the settings from it into a string? I basically just copy pasted the web functionality from other pages as I'm not really sure how it works, nor am I well versed in javascript.

Copy link
Collaborator

@mcspr mcspr Sep 17, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right now this sends key-values as-is, so every key is 'mapped' to the same 'input name=...' elem, this is done at the end of processData() func of custom.js

What I meant about e131Ch# approach is to do something like:

String base("e131Ch");
for (unsigned index = 0; index < lightChannels(); ++index) {
    String key(base + index);
    root[key] = getSetting(key); // without 'default' 2nd param, always returns String
}

Treating empty string as disabled and non-empty as e1.31 channel number, while always creating N-channels items. Same thing in the configuration.

Then, we either create html block programmatically like dczRelayTemplate, or always have html blocks in the index.html but hide them by default via display: none css style and add additional js code such as:

// processData() near the top...

if (key.startsWith("e131Ch")) {
    $("input[name=" + key + "]").show();
}

// ...rest of processData()

return _e131_enabled;
}

void e131Setup() {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should the config be purely though settings / UI, no use for build flags to pre-configure the defauls?

@CalcProgrammer1
Copy link
Author

Can you point to any simple client to test this out?

My OpenRGB project can control E1.31. You can get the latest release on GitLab:

https://gitlab.com/CalcProgrammer1/OpenRGB

You will need to create an e131.txt file in the same folder as the OpenRGB application. That file should contain something like:

e131_device_start
Espurna Bulb 1
num_leds=1
start_channel=1
start_universe=1
rgb_order=RGB
type=SINGLE
e131_device_end

e131_device_start
Espurna Bulb 2
num_leds=1
start_channel=4
start_universe=1
rgb_order=RGB
type=SINGLE
e131_device_end

This is the configuration I was testing with, two Espurna bulbs on universe 1. The first bulb was configured with channels 1/2/3, the second with channels 4/5/6.

@mcspr
Copy link
Collaborator

mcspr commented Sep 16, 2020

Thanks! Up and running.

I'll check out if Core's generic UDP server might work, too, since the only thing we want is to receive that giant struct and cast it. Might save a bit of .bin size, since mDNS already uses it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants