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

implement htp and ltp merging receivers #58

Merged
merged 3 commits into from
Jul 22, 2024
Merged

implement htp and ltp merging receivers #58

merged 3 commits into from
Jul 22, 2024

Conversation

mutec
Copy link
Contributor

@mutec mutec commented Mar 10, 2024

This is a small extension of @hansSchall PR. It implements LTP and HTP-merging additionally.

@mutec mutec force-pushed the mer-r branch 2 times, most recently from a6ccad0 to 3e1601b Compare March 10, 2024 18:42
src/receiver/ltp.ts Outdated Show resolved Hide resolved
src/receiver/abstract.ts Outdated Show resolved Hide resolved
@k-yle
Copy link
Owner

k-yle commented Mar 11, 2024

Thanks for the PR!

According to §6.2.3.4 of the E1.31 spec:

If merging or arbitration is implemented the algorithm used shall be declared in user documentation for the device.

So we need to be very clear about how the algorithms work. This is my understanding of your code:

HTP LTP
If the senders have a different priority

(§6.2.3 of E1.31)
per-universe (the highest priority sender wins)

Use case: Tracking backup console
per-universe (the highest priority sender wins)
However, non-0 values from previous packets are remembered

Use case: 2 consoles in different parts of the venue, whichever console is used most recently takes control.
If the senders have the same priority

(§6.2.3.1 of E1.31)
per-channel (the highest value wins)

Use case: parking a channel or controlling houselights, from a different console
per-channel (the latest value wins)

Use case: ??

@mutec
Copy link
Contributor Author

mutec commented Mar 11, 2024

Your table looks good to me.

HTP

Merging is processed per universe in any case. The current implementation supports priority per source only.

  • In case of different priorities:
    The sender using the highest priority wins for the whole universe.
  • In case of equal priorities:
    Every channel is processed on its and takes the highest value from a sender using that priority.

LTP

Merging is processed per universe in any case.

  • In case of different priorities:
    The sender using the highest priority wins for the whole universe.
  • In case of equal priorities:
    Every channel is processed on its own. It iterates over all senders using that priority and selects the value of the latest package/sender.

Interesting would be to

  • implement HTP merging using priorities per channel
  • overhauling the implementation and store only explicitly received values.
    Current behavior: When a sender sends channels 50-100 only, other channels will be set to 0. In case we store undefined or null or some kind of string like n/a, we could enhance LTP merging to support winning based on the last package including the channel.

In case you're wondering why:
I'm currently writing an integration for Node-RED wanting a maintained library following the standard: https://github.com/MysteryCode/node-red-sacn

mergedData.data[ch] = referenceData.data[ch] || 0;

for (const [, tmp] of data.universeData.servers) {
if (tmp.lastUpdate > referenceTime) {
Copy link
Owner

Choose a reason for hiding this comment

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

From #58 (comment):

LTP

[...]

  • In case of different priorities:
    The sender using the highest priority wins for the whole universe.

That sounds logical to me. However, the LTP algorithm doesn't consider the priority right now - I think we need something like this:

Suggested change
if (tmp.lastUpdate > referenceTime) {
if (tmp.lastUpdate > referenceTime && tmp.priority === data.maximumPriority) {

Also, it seems like the LTP algorithm has no way to reset a channel value to 0? Once a channel is set to a non-0 value, it is impossible to set that channel back to 0. I'm interested to know when this behaviour is useful?

@mutec
Copy link
Contributor Author

mutec commented Mar 14, 2024

I'm currently overhauling the implementation to support the difference between 0 and undefined for better handling. Might take some days to test it on my setup.

@k-yle
Copy link
Owner

k-yle commented Mar 17, 2024

I'm currently overhauling the implementation to support the difference between 0 and undefined for better handling. Might take some days to test it on my setup.

okay, I'm not sure if that's possible, because at the lowest level, channel values are encoded within a packet using 512 octets, each one can have a value between 0x00 (0) and 0xff (255). There is no way to set an octet to null or undefined.

There are some options:

  1. It is possible to only send data for part of a universe§7.6 of E1.31, but you always have to start from channel 1§7.4 of E1.31. The spec has a field called "First Property Address", but it must always be set to 0§7.4 of E1.31. For example, you could send:

    • channels 1 to 512
    • channels 1 to 100
    • but not channels 50 to 100
  2. Another possibility that the spec allows for is to send a packet with priority=0. In some non-standard implementations, this tells the receiver to clear all the data it has received from that sender?? need to find a reliable citation

  3. There also non-standard extensions to the spec, for example START Code 0xDDh is used by ETC[1]

But even with these 2 mechanisms, I don't think you can achieve the behaviour that you're after. So LTP can only work per-universe, not per-channel.

Copy link
Owner

@k-yle k-yle left a comment

Choose a reason for hiding this comment

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

I've rebased this PR and made some changes to the logic. LTP is now per-universe, since it's impossible to implement LTP per-channel.

I'm going to merge this but keep it undocumented for now, until I have time to add more test cases.

Thanks again for the PR :)

@k-yle k-yle merged commit 6fdc29b into k-yle:main Jul 22, 2024
8 checks passed
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.

2 participants