FAQs

Why Websockets and not DMX512 for prop control?

Asked by Dominic ...

The fundemental reason is the flexibility of the messaging format. Props need a lot more data namespace and value ranges than lighting fixtures.

We love DMX512 in the right place though, so we have a SWN-DMX unit that can pass events to DMX - more of this later.

Differences

DMX512 Essentially has a fixed data frame that passes a sequence of 512 channels where a value can range between 0-255. This is data in one direction.

The Set Wide Net uses Websockets to pass JSON formatted events. This gives an infinite namespace of devices each of which can use a rich data format.

Of great importantance is that props can publish their own events, this gives us two way communication.

Examples:

    
        {'e':'Counter1', 'd':{'target' : 'CounterValue', 'startvalue' : 47610000, 'direction' : 'reverse', 'rate' : 10, 'step' : 100 }} // Start Counting REVERSE at 47610000 10x faster rate in steps of 100 
        {'e':'LED1', 'd':{'sequence': [{'duty' : 100, 'rate' : 800},{'duty': 10, 'rate' : 100} ,{'duty':0,'rate' : 2000}]}}    // Fade 'egg' LED in a continous cycle from 100% to 10% to 0% at different rates
    

For more advanced behaviour we can use the Set Wide Net for Separations of concerns. A good example is simulation, where we can have a simple code block listening for events and responding to them.

You can see short video clip on this simulation example.

'Engine' Example

The code fragment below deals with two engine 'props' another fragment is listening to 'throttle' and 'load' controls which are practical props that an actor really interacts with. If the 'simulated' temperatures exceed limits the 'engine' prop will emit an 'Alarm' event. If the temperature increases to the 'failure' limit, the engines will shutdown, The 'Master Alarm' prop might listen for 'Alarm' events from the engines and emit a 'Master Alarm' event. The gauge and UI elements will for temperatures, revs, state etc and show them accordingly.

This is a simple example of how we can use the Set Wide Net to create a complex system.

    
        async def update_engine():
        alarm = False
        master_alarm = False
        engines = [engine1, engine2]
        while True:
    
            # Deal with the engines
            for engine in engines:
                engine.update()
                if abs(engine.temperature - engine.last_temperature) > 2:
                    message_queue.append({"e": engine.meter_temperature, "d": "{:.1F}".format(engine.temperature)})
                    engine.last_temperature = engine.temperature
                if abs(engine.rpm - engine.last_rpm) > 80:
                    message_queue.append({"e": engine.meter_rpm, "d": "{:.1F}".format(engine.rpm)})
                    engine.last_rpm = engine.rpm
                if engine.state != engine.last_state:
                    if engine.state == "Failure":
                        alarm = True
                        message_queue.append({"e": engine.failure_UI, "d": "visible"})
                    else:
                        if not alarm:
                            message_queue.append({"e": engine.failure_UI, "d": "hidden"})
    
            # Deal with the load meter
            if abs(engine1.load - engine1.last_load) > 0.05:
                message_queue.append({"e": "Stepper4", "d":  {"position" : int(engine1.load*100) }})
                engine1.last_load = engine1.load
    
            #deal with the Master Alarm
            master_alarm = False
            for engine in engines:
                if engine.state != engine.last_state:
                    if engine.state == "Alarm":
                        master_alarm = True
                        message_queue.append({"e": "UI4", "d": "visible"})
                    else:
                        if master_alarm == False:
                            message_queue.append({"e": "UI4", "d": "hidden"})
                    engine.last_state = engine.state
                        
            # rest a bit
            await asyncio.sleep(0.3)
    

You can see that different teams of prop makers can craft props that work in concert together whilst interacting with the actors such that the actors experience a script motivated realism.

Here's a tease of what we can do with DMX:

    
        {'e':'DMX512', 'd':{'channel' : 1, 'value' : 255}} // Turn on the first light to full brightness
    

And here's an example of our SWN-DMX unit performing autonomous actions on an event:

    
        {'e':'DMX1', 'd':{'fade': 4, 'channel' : 5, 'value' : 255}}
        {'e':'DMX1', 'd':{'fade': 2, 'channel' : 4, 'value' : 16}}
        {'e':'DMX1', 'd':{'fade': 1, 'channel' : 3, 'value' : 0}}
    

The above example shows 3 different channels of DMX fading to new values but at different rates. Once this event is received the SWN-DMX unit calculates all the intermediate values and sends the required DMX stream.