Skip to content
I-Tang Chiang (Eden) edited this page Jun 7, 2023 · 12 revisions

The OOCSI mission is to create a simple systems-interaction fabric for use by designers.

What is OOCSI?

OOCSI is a message-based communication framework that connects clients across different platforms or programming languages. OOCSI allows to send, receive and broadcast messages with arbitrary content.

There are two basic types of components in an OOCSI network: several clients and one server. The OOCSI server can either be running on your own computer (that's called "local") or it runs on a server in the cloud. There is more information about the OOCSI server.

OOCSI clients are the active components of an OOCSI system; they send and receive data, subscribe to channels, and synchronize their data with each other. Clients can come in many forms and sizes. Some of them are connecting to OOCSI from embedded platforms like Arduinos and ESPs, some others are connecting from a website, a desktop application, or a Python script. Therefore, we have prepared several different client libraries that you can include in your code and connect to OOCSI to send and receive data in a very simple way. You can find a simple example on the Getting Started page.

How to use OOCSI

Step 1 is to find an OOCSI server. If you are using OOCSI in education such as in class or project at the university, ask your teacher about the server. If you are planning to use OOCSI in research, your department might be running a server already. Alternatively, you can run your own OOCSI server. It's actually quite easy and great for local testing and troubleshooting.

Step 2 is to get started with your OOCIS client. Depending on the platform that you use for prototyping and making, you need to choose one of our client libraries. If you cannot find a fitting library, let us know, perhaps we can whip something up quickly.

And that's it for getting started.

Features

An OOCSI server does more than just the bare connectivity and communication tasks (receiving and dispatching messages). Over the years, we have added lots of useful tools to the server that make the overall prototyping experience with OOCSI just so much better. These features can be divided into message features, tools and services. Let's go.

Message features

Sending and receiving of messages is the basic interface for OOCSI. All clients support this functionality and that makes a message also a great interface for higher-level features that the server adds on top of the basic communication.

Delayed messages

The message feature is the message delay, which allows to delay the dispatch of a message by n seconds. This means that a client sends a message with the _DELAY attribute to the server, the server temporarily stores the message and sends it out after the delay has passed. You can delay any message by adding the _DELAY key with a number of seconds as the value. See the two examples in Java and Python below:

// example for delaying a message in Java/Processing
oocsi.channel("some_channel").data("some data", true).data("_DELAY", 30).submit();

Here we create a message to the channel some_channel and add a piece of data some data plus the key _DELAY and the number of seconds that the message should be delayed on the server. For example, if you want to delay a message for one hour, you would use 3600 or a day with 86400. The Python example is very similar, with the same result.

# example for delaying a message in Python
oocsi.send("some_channel", { "some data": True, "_DELAY": 30 })

What could you do with this? You could hand over data to another client on the channel that only becomes active at night. Or you could use the server to temporarily store a message for a day, and pick it up again tomorrow. You could use this feature for a timeout or reminder, be creative!

Retained messages

Another message feature is about retaining messages. This means that a message is kept on the server (in a channel) and it is sent to all clients that connect to the channel -- until a timeout passes. You can think of this as "pinning" a message to a channel, which is useful for clients on embedded platforms that go into "deep sleep" most of the time to save battery. Here is how you do it:

# example for retaining a message in Python
oocsi.send("some_channel", { "some data": True, "_RETAIN": 600 })

In this example, we "pin" the meesage to the channel some_channel until the timeout of 600 seconds, 10 minutes, has passed. Similar to the delayed message feature, you can use really long timeouts, up to 7 days.

Channel filters and transformations

Another interesting feature are channel filter and transformations. In short, you can subscribe to a channel and let the OOCSI server do some work for you: if you subscribe with a filter, only the messages on that channel that pass the filter condition will be sent to your client. If you use a transformation, you can let the OOCSI server automatically compute new values in the message, for instance, the mean value of an attribute over the last 10 messages or the min/max values of another attribute over the last 50 messages. You can also use more complex expressions and use filters in combination with transformations. More information on how to do this and the expression reference is here.

Channel presence

the more devices you want to design with, the more you need to know which devices are actually online at a given moment and can respond to messages or requests. Likewise, it can be important to know that a devices is not (anymore) subscribed to a channel. OOCSI has a special feature for these types of use-cases: channel presence. An OOCSI client can subscribe to presence information for a specific channel. It will receive messages about devices subscribing and unsubscribing / leaving the channel. Also there is a regular ping being sent, so device information on a channel can be kept up-to-date. Subscribing to presence information works like this:

oocsi.subscribe("presence(some_channel)", "presenceHandler");
//...

void presenceHandler(OOCSIEvent event) {
	// do something with the presence event
}

How do presence messages look like? Let's say a new client webclient_1641637024636 subscribes to testchannel, the resulting presence message would be:

{
	"channel":"testchannel",
	"join":"webclient_1641637024636"
}

When the client unsubscribes from testchannel the presence message is:

{
	"channel":"testchannel",
	"leave":"webclient_1641637024636"
}

The channel attribute is always given and denotes the channel that presence tracking applies to. The second key provides the type of presence event and possibly indicates from which clients on the channel this event originats. We have seen the join and leave key above already. Other keys are created and closed (without clients names) that indicate that the channel was created (with the first subscriber) or closed (with the unsubscribe of the last subscriber). The refresh key with client name indicates that the client just pinged the server. This event will only raised once every 10 seconds at most. Finally, there is a timeout key that is generated when a client on the channel does not respond anymore to server pings.

Tools

If you can access the OOCSI server with a browser (just enter the server address into Firefox, Chrome, Edge, Safari or else), then you can make use of the serverhosted OOCSI tools by clicking on the "tools" link in the upper right corner. The currently available OOCSI tools are animOOCSI. an animation tool for OOCSI data, OOCSImote, a remote control for sending data from a web-based user interface to an OOCSI client, and the dashboard that allows for easy plotting of OOCSI data from a channel.

Next to these tools, there are also three different pages for testing purposes. For example, the visual UI client that you can use to subscribe to a channel or send messages over a channel, from within your browser. This is great for testing and debugging your OOCSI communications. For instance, you might be sending data from a prototype to a channel and then to a second client. But the second client cannot receive anything or only wrong data arrives. This is a perfect use-case for the visual UI client; you subscribe in your browser to the same channel and can check what data actually reaches the OOCSI server from the first client. This often helps you make the next step in debugging the communication.

Services

An OOCSI server runs several internal OOCSI clients that each fulfill a specific purpose. We call them services here because they are always connected and operational.

Test client

This client will send test data to the channel testchannel. The data is structured in two message attributes position and color, and the data follows a sine / cosine pattern. So, next time when you want to test your OOCSI connection, you can just subscribe to the channel testchannel and a steady stream of messages will be delivered to you. This is often the first thing to check for a working OOCSI connection. Like this:

// example for Processing

void setup() {
	// create OOCSI connection
	// ...

	// subscribe to testchannel
	oocsi.subscribe("testchannel");
}

// events will be delivered here
void testchannel(OOCSIEvent event) {
	int color = event.getInt("color", -1);
	int position = event.getInt("position", -1);

	// ... do something with the values
}

The test client is used in some of the OOCSI examples, for instance, on the Processing platform. Check them out.

Time client

The time client sends time data to the channel timechannel every second. Specifically, a client that subscribes to this channel will receive a message that contains not only a timestamp, but also a formatted date-time string and the different components of the date and time as separate attributes. The message looks like this:

{
	"datetime":"2022-01-06T18:14:20", // formatted date-time string, 24 hour time format
	"dw":5, // day of week
        "s":20, // second
	"d":6, // day
	"h":18, // hour
	"y":2022, // year
	"M":0, // month
	"m":14, // minute
	"timestamp":1641489260015 // UNIX epoch timestamp
}

Time data can be useful on clients that do not have a real-time clock (RTC) or that are only connected to the OOCSI server not the Internet. A straight-forward way to trigger behavior at a certain time of the day is to subscribe to timechannel and run the messages through a few if-else conditions. Even simpler, subscribe to timechannel with a filter and only the requested time events reach the client:

// subscribe to time information with a filter
// in this case, receive only one message per hour on minute 26 and second 1
oocsi.subscribe("timechannel[filter(m=26&&s=1)]");

This combination of time data and filtering is particularly suited to embedded clients that don't havea lot of processing power and network bandwidth. Filtering time data cuts down the time information to the essentials.

Echo client

The echo client receives messages and bounces them right back to the sender. Send a message to echo and you should receive it back in a few milliseconds. Note that the echo'ed message is sent to the client handle directly, not a channel. So, you need to have a handler configured for the client. Apart from testing debugging, you can also use the echo client to measure the connection speed as round-trip time, that is, how long it takes to send and receive a message back from the server. Usually, you should measure a round-trip time of <50 milliseconds, but WIFI connections or a busy network can result in longer round-trip times. Just try it out.

HTTP Web request client

The HTTP web request client can make HTTP requests to websites for any client on the OOCSI network. This is useful for requesting updated information from a website and for communicating with web services via POST requests. Documentation for this client is TBD.

Event, client, and connection channels

Any OOCSI server supports three special channels that provide information about the current data flowing through the OOCSI system. Let's go through them one by one. The first channel is OOCSI_clients; if a client subscribes to this channel, it will periodic updates on the current list of clients on leave the OOCSI network. If you just want information on connects and disconnects, you can use OOCSI_connections. If a client subscribes to this channel, the client will receive messages when clients connect to the server or disconnect from it. Finally, there is OOCSI_events, a channel that logs all messages inside the system. Note that only the sender and recipient of the message will be shown, message data is not provided in this channel, except for a count of message attributes and the size of the message. The latter properties can be used for message visualisation or analysis.

If you are interested in more "meta" data about OOCSI devices, check out the heyOOCSI functionality.


How OOCSI works internally

The entire OOCSI ecosystem is open-source and available from GitHub. If you interested in understanding the OOCSI communication protocol or if you would like to implement an OOCSI client for a new platform, find some more information here: OOCSI protocol

How to reference the OOCSI system

When you design and prototype a system with OOCSI, you might need to reference the system in your documentation (a report, a paper, a website etc.). The easiest is to use a citation like this:

Funk, Mathias. (2019, May). OOCSI. Zenodo. http://doi.org/10.5281/zenodo.1321220

Zenodo badge License: CC BY-SA 4.0

BibTex

@misc{funk_mathias_2019_1321220,
  author       = {Funk, Mathias},
  title        = {OOCSI},
  month        = may,
  year         = 2019,
  doi          = {10.5281/zenodo.1321220},
  url          = {https://doi.org/10.5281/zenodo.1321220}
}