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

Sent data does not work / it doesnt send #2

Open
simpelMIC opened this issue Feb 24, 2024 · 9 comments
Open

Sent data does not work / it doesnt send #2

simpelMIC opened this issue Feb 24, 2024 · 9 comments

Comments

@simpelMIC
Copy link

simpelMIC commented Feb 24, 2024

Hi,
I have a problem using this package. I'm building a macOS application using Swiftui and I'm not able to control my lights with this package. I have a Raspberry Pi set up with OLA.
To explain the problem a bit further, yesterday I set up the Raspberry Pi. I checked the XCode Network (Debug) Monitor to look for Network Traffic, and indeed, I saw data was going out of my program into the pi. (Yes I checked the pi too). But no values seemed to change in the universe. I retried multiple times and tried different methods too. My current attempt is using UDP Unicast to a local IP address. (Yes I tried plugging every component into a switch, and yes it didn't work) I checked every reachability, and to my surprise when I used qlc+ everything worked out fine. So it seems the problem is on the side of this package. I hope to get some help or answer on this issue because the other one didn't really get any response.
Best regards,
MIC

let connection = Connection(endpoint: .hostPort(host: "192.168.178.178", port: .sACN), universe: 1)
connection.sendDMXData(Data([255, 0, 0, 0, 255]), priority: 200, isPreviewData: false)

In OLA:
Bildschirmfoto 2024-02-24 um 21 50 18
Bildschirmfoto 2024-02-24 um 21 50 30
Bildschirmfoto 2024-02-24 um 21 51 11

IN XCode:
Bildschirmfoto 2024-02-24 um 23 35 09

@dnadoba
Copy link
Owner

dnadoba commented Feb 27, 2024

My best guess is that you haven't the right entitlements setup for your macOS app which by default enables sandboxing. You will need the com.apple.security.network.client and com.apple.security.network.server entitlements for UDP connections.

This can be setup in the Xcode UI. Select your Xcode Project file, then your target and go to the Signing & Capabilities tab. Under "App Sandbox" select both checkboxes under Networking, Incoming Connections (Server) and Outgoing Connections (Client).

@simpelMIC
Copy link
Author

Hi dnadoba,
I have already made this change to my XCode Project. It still does not work. :)
Best regards,
MIC

Bildschirmfoto 2024-02-27 um 22 24 00

@dnadoba
Copy link
Owner

dnadoba commented Feb 27, 2024

Hm okay. I have only ever used it with UDP broadcast. Maybe try this.
Another thing I would try is setting the connection.connection.stateUpdateHandler to a closure that prints the state.
In addition, instead of using connection.send(..., completion: .idempotent) in sendDMXData(...) you could change that to take a closure as well and print the error, if any is present. You will need to change that in this package though. Just clone it and drag & drop it into your Xcode project to edit it. This should give you a better idea what's going on.
I can also recommend using Wireshark to see if any packets are send out.

@simpelMIC
Copy link
Author

So this is the class I've set up

class e131sACNController: ObservableObject {
    @Binding var dmxChannels: [DMXChannel]
    @Published var isStreaming = false
    
    //Settings
    var host: NWEndpoint.Host = "192.168.178.178"
    var port: NWEndpoint.Port = .sACN
    var universe: UInt16
    
    init(dmxChannels: Binding<[DMXChannel]>, universe: UInt16) {
        self._dmxChannels = dmxChannels
        self.universe = universe
        print("sACN Initialized")
    }
    
    func sendDMXData() {
        let connection = Connection(endpoint: .hostPort(host: host, port: port), universe: 1)
        connection.sendDMXData(Data([255, 0, 0, 0, 255]), priority: 100, isPreviewData: false)
    }
}

I've already used Wireshark to compare the data packets sent by the sACN Package and QLC+. The packages sent by QLC+ had a size of about 600 bytes while the ones from the package only had a size of around 40.
UDP Multicast doesn't work in my case, because the Raspberry Pi doesn't receive the packages sent. If I'm using UDP Unicast (endpoint: .hostPort(host: host, port: port)) the Pi receives the packages but OLA doesn't recognize them.
Regards,
MIC

@dnadoba
Copy link
Owner

dnadoba commented Feb 28, 2024

You need to keep the Connection object alive or otherwise the connection will be cancelled on deinit, in you case at the end of the your sendDMXData function and the UDP message will likely not be send. Consider initialising the Connection in the init and keeping it as a stored property.

40 bytes is definitely wrong, it needs to be a lot more. You can also try adding padding zeros at the end to make the whole DMX data 512 bytes long, maybe the other side always expects 512 bytes of DMX data.

@dnadoba
Copy link
Owner

dnadoba commented Feb 28, 2024

Also, please try out the demo and modify it to your needs to see if that works on your setup: https://github.com/dnadoba/sACN/blob/master/Sources/sACNDemo/main.swift

@simpelMIC
Copy link
Author

Ok I changed some things in my code and now I think the connection is fine. It monitors perfectly in the XCode Network Monitor and the length is 600 bytes with my normal channel variables.

class e131sACNController: ObservableObject {
    @Binding var dmxChannels: [DMXChannel]
    @Published var isStreaming = false
    
    var host: NWEndpoint.Host = "192.168.178.178"
    var port: NWEndpoint.Port = .sACN
    var universe: UInt16
    
    var connection: Connection
    
    init(dmxChannels: Binding<[DMXChannel]>, universe: UInt16) {
        self._dmxChannels = dmxChannels
        self.universe = universe
        self.connection = Connection(endpoint: .hostPort(host: host, port: port), universe: universe)
        print("sACN Initialized")
    }
    
    func timer() {
        DispatchQueue.main.asyncAfter(deadline: .now() + 1/20) {
            if self.isStreaming == true {
                self.timer()
                self.sendDMXData()
            }
        }
    }
    
    func startStreaming() {
        isStreaming = true
        timer()
    }
    
    func stopStreaming() {
        isStreaming = false
    }
    
    func sendDMXData() {
        let dmxValues = dmxChannels.map { UInt8($0.value) }
        let dmxData = Data(dmxValues)
        
        print(dmxValues)
        
        connection.sendDMXData(Data(dmxData), priority: 100, isPreviewData: false)
    }
}

The Log looks like this:

[255, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]

But it's still not working... My lamp didn't light up. QLC+ works btw.
So what seems to be the problem? If you have any questions regarding the rest of my project feel free to ask :) But it's also listed on my github.

A DMXChannel looks like this:

struct DMXChannel: Equatable, Identifiable, Codable {
    var id = UUID()
    var value: Double //Value of Channel 0-255
}

and I create 512 of them when a new project is made.
Regards,
MIC

@dnadoba
Copy link
Owner

dnadoba commented Feb 28, 2024

You can try to use the sACNView app and check if the values are correctly received. Use your own IP for testing this.
Maybe your Raspberry Pi only accepts the first "connection". Try restarting and sending data first from your app before QLC+.
Double check IP and also the Port.
Double check the DMX values you send if they map to the fixture you are using.

@simpelMIC
Copy link
Author

Ok thanks for the help. It doesn't directly work, but if I pass it through QLC+ it works. I think my OLA didn't accept the signals for some reason. In sACNView it looked good and it worked in QLC+ too. So thanks a lot :)
Regards,
MIC

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

No branches or pull requests

2 participants