Intermediate OOCSI topics

So, you went through the OOCSI basics and you want more? Sure thing. Here we will explain a few intermediate topics of the OOCSI system.

Quick intro? You got it.

Ok, so the intermediate section of learning about OOCSI is structured into sharing data, awareness and presence, filters and transformations, and the call-response pattern. Let’s go.

Sharing data with OOCSI variables

sequenceDiagram
    autonumber
    actor A as Client A (UI Slider)
    participant OOCSI as OOCSI Server (Channel 'shared_controls')
    actor B as Client B (Python Service)
    actor C as Client C (ESP32 Actuator)

    Note over A,C: All clients link to variable 'slider_value'
    A->>A: slider.set(85)
    A->>OOCSI: Broadcast {"slider_value": 85}
    par Fan-Out Update
        OOCSI->>B: Deliver update
        B->>B: Local variable becomes 85
    and
        OOCSI->>C: Deliver update
        C->>C: Local variable becomes 85 (Actuator moves)
    end

In the first video we talk about sharing data in OOCSI by means of “variables”. Variables make data exchange easy, because you don’t have to prepare and capture data at the event or message level; you can just let the code share data in certain variables automatically. So, when the value of the variable changes all other OOCSI clients linked to this variable will get updated. This works in our Java, Python and JavaScript clients. Now that we have variables, we can make them a little smarter: give them reference values, constraints (limit their range), smoothen and throttle them, and use them as generators to create a steady stream of values.

How to use OOCSI variables in code

In Python

# Link to variable 'slider_value' on channel 'shared_controls'
slider = oocsi.variable('shared_controls', 'slider_value')

# Read current value
print("Current value:", slider.get())

# Update value (automatically broadcasts to all other clients)
slider.set(85)

In JavaScript (Web Browser / Node.js)

// Link variable on channel 'shared_controls' with a 200ms throttle to prevent bus congestion
let slider = OOCSI.variable("shared_controls", "slider_value", 200);

// Read current value
console.log("Current value:", slider());

// Update value
slider(85);

In Java / Processing

// Link a typed variable on channel "shared_controls"
OOCSIInt slider = new OOCSIInt(oocsi, "shared_controls", "slider_value", 0);

// Read current value
int val = slider.get();

// Update value
slider.set(85);

Awareness, filtering and transformations on OOCSI channels

In the second video, we explain how to track presence (of clients) on OOCSI channels automatically. Then we go into the message filtering facilities that allow for easy filtering of messages on a channel, directly on the server. You can use simple expressions of message data, e.g., temperature > 25 and only receive the messages with matching data items. You can also let the OOCSI server compute aggregates for you, for instance, the average of the last 30 events. The same expressions can be used to create transformations, that is, new data attributes that are computed automatically. And of course, you can combine both filtering and transformations.

Read the dedicated reference guides for Clients and Channels (Presence) and Filter & Transform.

The call-response pattern for synchronous messaging

sequenceDiagram
    autonumber
    actor Caller as Caller Client
    participant Server as OOCSI Server
    actor Responder as Service Responder

    Caller->>Server: Call 'color_mixer': {r:255, g:128, b:0}<br/>(passes _MESSAGE_ID & caller handle)
    Server->>Responder: Forward call event
    Note over Responder: Computes hex color "#ff8000"
    Responder->>Server: Send reply: {hex: "#ff8000", _MESSAGE_ID}
    Server->>Caller: Deliver response payload
    Note over Caller: Promise resolves / Callback executed

The last intermediate video shows how to communicate with OOCSI in a synchronous way. So, not fire-and-forget, but waiting for a response from a client or channel. You can implement a responder on an OOCSI client and use this to communicate synchronously with this client.

How to use Call-Response in code

In Python

# 1. Provide a service (Responder)
@oocsi.responder('color_mixer', 'mix')
def handle_mix(data):
    r = data.get('r', 0)
    g = data.get('g', 0)
    b = data.get('b', 0)
    return {'hex': f"#{r:02x}{g:02x}{b:02x}", 'status': 'success'}

# 2. Call the service and await the result (Caller)
result = oocsi.call('color_mixer', 'mix', {'r': 255, 'g': 128, 'b': 0}, timeout=2.0)
if result:
    print("Mixed color:", result['hex'])

In JavaScript (oocsi-web.js)

// 1. Provide a service (Responder)
OOCSI.register("color_mixer", (data, response) => {
    let r = data.r || 0;
    let g = data.g || 0;
    let b = data.b || 0;
    response.hex = "#" + ((1 << 24) + (r << 16) + (g << 8) + b).toString(16).slice(1);
});

// 2. Call the service and receive result in callback (Caller)
OOCSI.call("color_mixer", { r: 255, g: 128, b: 0 }, 2000, (result) => {
    console.log("Mixed color:", result.hex);
});

In Java

// 1. Provide a service (Responder)
new Responder(oocsi, "color_mixer") {
    @Override
    public void respond(OOCSIEvent event, Map<String, Object> response) {
        int r = event.getInt("r", 0);
        int g = event.getInt("g", 0);
        int b = event.getInt("b", 0);
        response.put("hex", String.format("#%02x%02x%02x", r, g, b));
    }
};

// 2. Call the service (Caller)
OOCSICall call = new OOCSICall(oocsi, "color_mixer", 2000);
call.data("r", 255).data("g", 128).data("b", 0).send();
if (call.hasResponse()) {
    System.out.println("Mixed color: " + call.getFirstResponse().get("hex"));
}

Are you ready for more? Head over to the advanced topics!


Copyright © 2013-2026 Mathias Funk.

This site uses Just the Docs, a documentation theme for Jekyll.