k-yle / sACN

💡 🎭 Send & Receive sACN data (DMX over IP) in node.js
https://npm.im/sacn
Apache License 2.0
28 stars 12 forks source link

implement htp and ltp merging receivers #58

Closed mutec closed 1 month ago

mutec commented 5 months ago

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

k-yle commented 5 months ago

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 commented 5 months ago

Your table looks good to me.

HTP

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

LTP

Merging is processed per universe in any case.

Interesting would be to

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

mutec commented 5 months ago

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 commented 5 months ago

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.