-
-
Notifications
You must be signed in to change notification settings - Fork 1.7k
[dmx] fixes #4774 #4775
[dmx] fixes #4774 #4775
Conversation
| private static Logger logger = LoggerFactory.getLogger(DmxController.class); | ||
|
|
||
| private static int TRANSMIT_FREQUENCY_MS = 35; | ||
| private int transmitRefreshMs = 0; // default is send all updates |
There was a problem hiding this comment.
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)
There was a problem hiding this comment.
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); |
There was a problem hiding this comment.
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) | ||
| */ |
There was a problem hiding this comment.
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; |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed
|
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
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>
|
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>
|
Since nobody seems to object, how do we proceed on this one? |
watou
left a comment
There was a problem hiding this 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(); |
There was a problem hiding this comment.
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")) { |
There was a problem hiding this comment.
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 |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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; |
There was a problem hiding this comment.
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) | ||
| */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
enum type
|
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 |
|
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. |
There is no issue with nesting it where you did. Java enums are implicitly static, so that's good too.
No need to unless you want to, since maintainers squash and merge in one step nowadays. Thanks for your good work, @J-N-K! |
|
This is working like a charm. I think we can merge it. |
|
It's four weeks now since this is ready for merge. Please let me know if I should close this PR |
|
lgtm, thanks for the reminder @J-N-K. |
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