Skip to content

Underlying Logic

Arian edited this page Jan 4, 2026 · 3 revisions

0 Template

Important

To maintain a high standard of documentation, all entries in this section must adhere to this structure. Our goal is to preserve the project's "institutional memory" by ensuring every contribution is:

Insightful: Clearly explains the reasoning to future contributors.

Concise: Avoids redundancy and stays focused on the core problem.

Chronological: Documents the evolution of the thought process as it happened.

The Decision Template

# Title: [Short, Descriptive Name of the Decision]

## 1. Context & Problem Statement**

Describe the specific challenge or technical limitation we encountered. What was the "pain point" that triggered the need for a decision?

## 2. Alternatives Considered

List the 2–3 different approaches we evaluated. Why were these options on the table?

Option A: [Description]

Option B: [Description]

## 3. The Resolution (The Chosen Path)

State clearly which solution was implemented and when.

## 4. Trade-offs & Consequences

What did we sacrifice? (e.g., "We prioritized long-term maintainability over immediate execution speed.") Describe the "debt" or specific benefits we accepted.

## 5. The Underlying Logic

The "Tribal Knowledge" section. Explain the specific mental model, project values, or unique insights that led to this specific conclusion.

## 6. Reference & Discussion

To see the full technical debate and implementation details, refer to the original threads:

Issue: #

Pull Request: !

💡 Contribute Your Knowledge

Notice something missing? Our "Underlying Logic" is only as strong as our documentation. If you were involved in a significant architectural pivot or a complex bug fix that required deep reasoning, please add it here. Documenting your thought process today saves hours of frustration for the contributors of tomorrow. If you aren't sure if a decision is "important enough," err on the side of caution and document it!

1 Websocket based Frontend-Backend communication using commands

1.1 Context & Problem Statement

Hyperion is a fast web-first DMX controller which uses modern web technologies to control stage lights. In later versions hyperion could be extended with a collaboration mode where many users can work on the same showfile.

Problem: Updates done on the UI (e.g. moving faders) must happen immideately. Also should hyperion have the opportunity to send changes back to the webbrowser without polling.

image

1.2 Alternatives Considered

Normal HTTP requests (e.g. POST, PUT, DELETE, GET) are too slow and require re-authentification with each request.

Option A: Custom Protocol. A custom protocol would allow hyperion to send as little data as possible from the frontend to the backend which allows infinite customisation.

Option B: A dedicated websocket. Websockets are a common tool of the internet. Many applications use them and they are browser native. Websockets are also incredibly fast and allow updates on both sides.

1.3 The Resolution (The Chosen Path)

Option B was chosen as the main communication route from the frontend to the backend. For further development, hyperion uses /dmx/engine exclusively for Frontend-Backend communication. Due to the speed, using a websocket is prefered over a HTTP request.

1.4 Trade-offs & Consequences

One major tradeoff is the command routing. Normal HTTP requests can be handled using different REST-Endpoints, whereas the websocket must be able to handle all requests efficiently. Since all DMX procedures, updates etc are handled by one websocket, an efficient Routing must be implemented.

As a consequence, all communication from the frontend to the backend happens in commands.

Example command:

{
  "cmd": "shows.create",
  "data": {
     "name": "Test Show 1"
   }
}

Procedure:

  1. User triggers a command on the frontend
  2. frontend sends a payload to the websocket
  3. payload gets directly redirected to the DMXRouter
  4. DMXRouter retrieves the right Pydantic Model, function and required role using the specified command
  5. If the router finds errors (e.g. wrong JSON, insufficient permission, unknown command), it will raise an error. Otherwise call the function.

1.5 The Underlying Logic

Popular DMX Controllers all have their own "scripting language". Instead of the router, we could create our own hyperion language and send those in a simple string over the websocket. I actively want to avoid writing a custom interpreter for DMX commands.

A custom language would add two layers of complexity:

  1. Hyperion users would have to learn the language at some point
  2. Implementing new features would require us to change the language definition (which is again madness to maintain)

Using a websocket and well-defined JSONs, anyone can simply add functionalities using a decorator and a simple JSON schema without messing with a custom language.

1.6 Reference & Discussion

To see the full technical debate and implementation details, refer to the original threads:

Issue: #

Pull Request: !