这是indexloc提供的服务,不要输入任何密码
Skip to content
This repository was archived by the owner on May 17, 2021. It is now read-only.

Conversation

@J-N-K
Copy link
Member

@J-N-K J-N-K commented Nov 13, 2016

Adds configurable DMX transmit refresh. The "refresh" configuration option defaults to -1 (never refresh), which is compatible with the current implementation. A value of 0 would refresh every 35ms, another value would transmit data if it has been changed or the last transmission is more than (value) ms in the past.

Signed-off-by: Jan N. Klug jan.n.klug@rub.de

private static Logger logger = LoggerFactory.getLogger(DmxController.class);

private static int TRANSMIT_FREQUENCY_MS = 35;
private int transmitRefreshMs = 0; // default is send all updates
Copy link
Contributor

Choose a reason for hiding this comment

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

This disagrees with the PR comment:

The "refresh" configuration option defaults to -1 (never refresh)

Copy link
Member Author

Choose a reason for hiding this comment

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

fixed.


logger.trace("Starting Dmx transmitter ...");
transmitter = new DmxTransmitter(this);
transmitter.setTransmitRefresh(transmitRefreshMs);
Copy link
Contributor

Choose a reason for hiding this comment

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

Could the variables/members/methods all use the phrase refreshInterval so the changed code is easier to follow?

*
* @param refreshInterval
* interval in ms (if output did not change)
*/
Copy link
Contributor

Choose a reason for hiding this comment

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

setRefreshInterval as mentioned above?

*/
public DmxTransmitter(DmxService service) {
this.service = service;
lastTransmit = 0;
Copy link
Contributor

Choose a reason for hiding this comment

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

Could lastTransmit be initialized to 0 above, instead of one private member being initialized that way, and the other initialized in the constructor?

Copy link
Member Author

Choose a reason for hiding this comment

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

fixed

@J-N-K
Copy link
Member Author

J-N-K commented Nov 14, 2016

I have incorporated all comments. However, after re-reading E1.11 (DMX 512) and E1.31 (sACN) as well as ArtNet, I come to the conclusion that the "never-refresh-policy" is plain wrong when it comes to standards compliance.

E1.11 states for DMX512 that there is a continous data stream (with a maximum MARK before BREAK of 1s), and defines that longer periods are considered as Data Lost (8.9). The standard does not define how a receiver should behave if that occurs, besides that it should remain operational for at least 60s. So after 60s without signal a standard compliant receiver could even turn off (9.2).

E1.31 defines that if the output is not changing, the last packet should be re-transmitted three times. After that the sender is allowed to pause sending for 800-1000ms (6.6.2).

ArtNet defines that non-changing DMX data should be retransmitted at approximately 4s intervals, but it is recommended for compatibility with sACN to re-transmit after 800-1000ms (chapter ArtDmx, p. 46).

So my proposal would be to

  1. either change the default to "send always", and transmit three unchanged packets before suppressing further updates for the configured refreshTimeout or
  2. change the configuration option to "suppressRetransmission" with a default of "false" and suppressing re-transmission of unchanged data for 800ms after sending three packets.

Sorry, I didn't think about that before.

(Sorry #2, closed PR by accident).

Signed-off-by: Jan N. Klug <jan.n.klug@rub.de>
@watou
Copy link
Contributor

watou commented Nov 18, 2016

Hi @J-N-K, could you circulate your thoughts about proper refresh handling to other DMX users on the forum (unless you've already done that), and make sure your proposed changes don't meet thoughtful disagreement? Your focus on this is probably a rare opportunity to get this right vis-a-vis standards and real-world operation. So I will mark this PR as awaiting feedback until the related issues are all well considered. Thanks for your contributions!

… on repeat"

Signed-off-by: Jan N. Klug <jan.n.klug@rub.de>
@watou watou changed the title fixes #4774 [dmx] fixes #4774 Nov 24, 2016
@J-N-K
Copy link
Member Author

J-N-K commented Nov 25, 2016

Since nobody seems to object, how do we proceed on this one?

Copy link
Contributor

@watou watou left a comment

Choose a reason for hiding this comment

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

Hi @J-N-K, here are a few more review comments.

logger.debug("Setting connection from config: {}", connectionString);
}
// refresh timeout (i.e. interval between transmits if nothing changed)
String configuredRepeatMode = ((String) config.get("repeatMode")).toLowerCase();
Copy link
Contributor

Choose a reason for hiding this comment

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

This will cause an NPE if repeatMode is not configured in the configuration, but in order to be compatible for existing users, the code must allow that no repeatMode is configured. See my advice earlier about using an enum type.

// refresh timeout (i.e. interval between transmits if nothing changed)
String configuredRepeatMode = ((String) config.get("repeatMode")).toLowerCase();
if (StringUtils.isNotBlank(configuredRepeatMode)) {
if (configuredRepeatMode.matches("always")) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Use the enum type as suggested, or if not, equalsIgnoreCase instead of matches here and below You can then remove the NPE possibility by removing the toLowerCase above.

private static Logger logger = LoggerFactory.getLogger(DmxController.class);

private static int TRANSMIT_FREQUENCY_MS = 35;
private int repeatMode = DmxTransmitter.REPEAT_MODE_ALWAYS; // default is send every update
Copy link
Contributor

Choose a reason for hiding this comment

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

Instead of int, it would be safer to use an enum type. Here is the construct that would seem to suit this optionally configured value.

Copy link
Member Author

Choose a reason for hiding this comment

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

Good idea. A question regarding the coding style: should this enum be below DmxTransmitter (as are the constants now) or seperate?


public static final int REPEAT_MODE_ALWAYS = 0;
public static final int REPEAT_MODE_NEVER = 1;
public static final int REPEAT_MODE_REDUCED = 2;
Copy link
Contributor

Choose a reason for hiding this comment

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

These are more suitably an enum type.

*
* @param refreshInterval
* interval in ms (if output did not change)
*/
Copy link
Contributor

Choose a reason for hiding this comment

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

enum type

Signed-off-by: Jan N. Klug <jan.n.klug@rub.de>
@watou
Copy link
Contributor

watou commented Nov 25, 2016

The code looks good to me. If you report back that this latest version of the PR is working reliably, and will continue to work the same (or better) for other existing users, I think it's ready to merge. Also please update the wiki to reflect the repeatMode parameter and its detailed meaning. Thanks!

@watou watou added this to the 1.9.0 milestone Nov 25, 2016
@J-N-K
Copy link
Member Author

J-N-K commented Nov 25, 2016

I'll test that for some days and report back. Do you think that positioning the enum in DmxTransmitter is a good place? If so, I'll squash all commits into one.

Thanks for your guidance.

@watou
Copy link
Contributor

watou commented Nov 25, 2016

Do you think that positioning the enum in DmxTransmitter is a good place?

There is no issue with nesting it where you did. Java enums are implicitly static, so that's good too.

If so, I'll squash all commits into one.

No need to unless you want to, since maintainers squash and merge in one step nowadays.

Thanks for your good work, @J-N-K!

@J-N-K
Copy link
Member Author

J-N-K commented Nov 30, 2016

This is working like a charm. I think we can merge it.

@J-N-K
Copy link
Member Author

J-N-K commented Dec 28, 2016

It's four weeks now since this is ready for merge. Please let me know if I should close this PR

@J-N-K J-N-K closed this Dec 28, 2016
@J-N-K J-N-K reopened this Dec 28, 2016
@watou watou merged commit b9a08b4 into openhab:master Dec 28, 2016
@watou
Copy link
Contributor

watou commented Dec 28, 2016

lgtm, thanks for the reminder @J-N-K.

@J-N-K J-N-K deleted the fix-dmx-refresh branch December 31, 2016 15:13
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants