Home Soundcraft User Forum Soundcraft Mixing Consoles

UI12 websocket connection

Hey everyone!

I'm playing around with my UI12 and communicating with it via websockets. I've found some projects on the web doing a similar thing, e.g. this one: https://github.com/fmalcher/soundcraft-ui/blob/main/packages/mixer-connection/src/lib/mixer-connection.ts
Also, there are videos on YouTube demonstrating how to control the interface with a CLI script and receiving its state changes from the network connection. Alas, I'm unable to reproduce it. Here is a minimal version of what I'm working on, written down in Python:

import asyncio
import sys
import time

from websockets import connect  # lib installed with pip

alive = "GET /raw HTTP1.1\n"


async def conn(host, port):
    async with connect(f"ws://{host}:{port}") as ws:
        await ws.send(alive)
        print(await ws.recv())
        while True:
            await ws.send(alive)
            message = await ws.recv()
            if "SET" in message:
                print(message)
            time.sleep(1)  # can be omitted without effect


asyncio.run(conn(sys.argv[1], sys.argv[2]))

This works fine for a couple of seconds, during which I receive the unit's full state and updates from interacting with the web interface, but after that I only receive empty messages on my websocket.

I can control my device with the Soundcraft Midi Mixer application just fine, so I doubt there is a fundamental difference in the protocol between my UI12 and e.g. the UI24r, which most examples on the web refer to, as well as that I'm experiencing networking issues.
I also tried using a raw TCP socket, which gave me the same results (communication works for a few seconds an then dies down). My target language is Rust, where I can achieve the same (I just chose python for brevity here), so it's also not an implementation detail of either Python's or Rusts's websocket/TCP stream API that's spoiling my mood here.

Has anybody here ever done something comparable and knows what I'm doing wrong?

Comments

  • ruben018ruben018 Posts: 1
    edited July 2022
    Hi Aarkon , If u want to keep a stable connection with the mixer u can use WebSocket-client instead of WebSockets. And after receiving few messages it receives blank messages, whereas in WebSocket client on message function receives whenever their is a change in parameters. Ui12 , 16, 24r all works On same fundamentals principle WebSocket tcp
  • _Aarkon__Aarkon_ Posts: 2

    Funny how things coincide sometimes, it's been just a few days since I found a fix/workaround for the problem myself.
    tldr: Whenever I receive a ping-message, I have to send a certain message back. This is my working implementation in Rust (the language I wanted to use anyway):

    use std::str;
    
    use tungstenite::connect;
    use tungstenite::Message::Text;
    use url::Url;
    
    const ALIVE: &str = "3:::ALIVE"; // [1]
    const PING: u8 = 0x9;
    const MIXER_URL = "ws://10.10.1.1"; // adapt to your specific use case
    
    fn main() {
        env_logger::init();
    
        let (mut socket, response) =
            connect(Url::parse(MIXER_URL).unwrap()).expect("Can't parse the mixer URL");
    
        println!("Connected to the server");
        debug!("Response HTTP code: {}", response.status());
        debug!("Response contains the following headers:");
        for (ref header, _value) in response.headers() {
            debug!("* {}", header);
        }
    
        loop {
            let msg = socket.read_message().expect("Error reading message");
    
            if msg.to_string().contains("SETD") { 
                trace!("Received: {}", msg);
            }
    
            if msg.to_string().contains(&PING.to_string()) { // [2]
                socket.write_message(Text(ALIVE.into())).unwrap();
            }
        }
    }
    

    A few things to take note of (see annotations in the code):

    • [1] This string is sent out by the web interface once per second, you can observe it in the web sockets tab of your web developer toolkit. IIrc, it has to be this exact string you send to the UI12 yourself for the connection not die off.
    • [2] The tungsten library not only says it automatically responds to ping/pong messages appropriately, but also has a dedicated method for checking if a something is a ping or pong-message (e.g. msg.is_ping()). Both ways of operation don't work in conjunction with at least my UI12 though. I don't know if it's the library's fault or if the mixer meddles with the protocol messages, but I have to perform this sort of manual check & action.

    The above code however keeps the connection alive and will print (or rather trace!) any control signals the mixer confirms to have received.

Sign In or Register to comment.