tesira-web-control

tesira-web-control

Docker app from clausefoto's Repository

Overview

Control Biamp Tesira main and subwoofer volume from a phone or tablet browser. Requires a reachable Tesira DSP with Telnet enabled. Set your instance tags and channel counts during installation, or change them in the dashboard. Gang links dashboard channel sliders; it does not change DSP block ganging. Trusted local networks only; no authentication. Preset selection is planned.

Tesira Web Control

A mobile-friendly dashboard for main and subwoofer volume on a Biamp Tesira DSP. Runs as one Docker container on Unraid, with no runtime npm dependencies.

Why this exists

Biamp Canvas is Windows-only control software, so its control surfaces cannot run natively on iPads, iPhones, or Android phones. I wanted a simple way to adjust my Tesira system from my phone without opening a Windows computer.

Tesira Web Control provides a browser-based dashboard hosted on my Unraid server. The server communicates directly with the DSP using Tesira Text Protocol (TTP), while a phone or tablet only needs a browser on the local network. The initial goal is straightforward: main and subwoofer volume control, with preset buttons planned for later.

Biamp's Canvas system requirements list Windows as the supported operating system. This dashboard is an independent project focused on a small set of everyday controls.

Status

Working on the target Unraid and Biamp Tesira DSP setup. The owner has confirmed that the dashboard and volume adjustments work properly after the persistent Telnet connection update resolved the earlier delay. No measured hardware latency is claimed.

The automated suite has 19 passing tests covering TTP, refresh behavior, configurable channel targeting, saved settings across restarts, and stale-mapping rejection. The new settings panel and mappings still need verification on physical hardware. Physical disconnect/recovery testing and compatibility with other Tesira designs are not yet confirmed.

Features

  • Editable Main and Subwoofer instance tags (defaults: Level5 and Level4).
  • Channel-count dropdowns (1–32) for each group.
  • Gang on: one slider sets the selected channels equally. Gang off: individual channel sliders.
  • Settings saved across restarts in a persistent Docker volume.
  • Large dB readouts, sliders, and 0.5 dB adjustment buttons.
  • Current levels read on connection; no startup/reconnect volume defaults.
  • Actual values refreshed every three seconds while the page is visible.
  • Configurable limits enforced by the backend.
  • Readback after writes and clear errors for partial main updates.
  • Controls disabled when disconnected or a volume/settings write is in progress.

Upcoming feature

Preset selection: choose and recall saved Tesira presets directly from the dashboard. This feature is planned and is not available yet.

Screenshot

The running dashboard, showing main and subwoofer volume controls.

Tesira Web Control dashboard with main volume and subwoofer sliders

Unraid Community Applications

Beta submission packaging is included in templates/tesira-web-control.xml and ca_profile.xml. The published-image target is ghcr.io/clausefoto/tesira-web-control:beta. Check the Actions builds and publishing guide for image availability and remaining submission steps. Inclusion in the Apps catalog is pending Community Applications validation and review.

The Unraid installation form provides initial tags, channel counts, and Gang settings. Saved dashboard settings take priority.

Quick start on Unraid

Run in the Unraid terminal:

mkdir -p /mnt/user/appdata/tesira-web-control
git clone https://github.com/clausefoto/tesira-web-control.git /mnt/user/appdata/tesira-web-control
cd /mnt/user/appdata/tesira-web-control
cp .env.example .env
nano .env

Replace DSP_HOST=192.0.2.10 with your DSP's actual IP address. Review the volume limits, save, and exit. The example address is deliberately nonfunctional.

Build and launch, without needing the Compose plugin:

docker build -t tesira-web-control:local .
docker run -d --name tesira-web-control --restart unless-stopped \
  -p 8088:8088 --env-file .env \
  -v tesira-web-control-data:/data tesira-web-control:local

Or, if Docker Compose is installed:

docker compose up -d --build

Use one launch method. Open http://<unraid-address>:8088 on your phone on the home Wi-Fi. Save a home-screen shortcut if desired.

The plain docker run command always publishes port 8088; to change it, change its left-hand port number (for example -p 8090:8088). WEB_PORT in .env applies to Compose only.

First hardware check

  1. Open the dashboard and verify its readouts match Tesira. Opening it does not write any settings.
  2. Make a small downward sub adjustment and verify it in Tesira.
  3. Make a small downward main adjustment and verify all six channels.
  4. Change a level in Tesira and confirm the dashboard follows.
  5. Test DSP disconnection and recovery.

With Gang on, adjustments set all configured channels in that group to the same value. With Gang off, each channel has its own slider. If channels differ, the dashboard lists them before adjustment. Main channel writes are sequential, not atomic: a failure can leave only some channels changed. The app stops on the first failure, shows an error, and reads actual levels on the next refresh. It never automatically rolls back or retries a volume write.

Configuration

Variable Default Meaning
DSP_HOST documentation-only example address DSP control-network IP
DSP_PORT 23 Telnet port
MAIN_TAG / SUB_TAG Level5 / Level4 Initial instance tags
MAIN_CHANNELS / SUB_CHANNELS 6 / 1 Initial channel counts (1–32)
MAIN_GANG / SUB_GANG true / true Initial linked controls; true or false
PUID / PGID 1000 / 1000 Service identity; Unraid template uses 99 / 100
WEB_PORT 8088 Compose host port
PORT 8088 App listen port; leave at 8088 in Docker
MAIN_MIN_DB / MAIN_MAX_DB -24 / 12 Main slider limits
SUB_MIN_DB / SUB_MAX_DB -100 / 12 Sub slider limits

Open Settings in the dashboard to enter each group’s exact instance tag, choose its channel count, and switch Gang on or off. Channel counts select channels 1 through N; they do not create DSP channels. Gang links the dashboard controls and does not change the DSP block’s own ganging. The defaults preserve the original design: main Level5 / 6 channels / Gang on; sub Level4 / 1 channel / Gang on.

Saving settings does not write volume levels to the DSP. Docker stores settings in /data/settings.json; preserve the tesira-web-control-data volume when recreating the container. Outside Docker, settings use ./data/settings.json. Set SETTINGS_FILE to override the path. Native DSP blocks that require channel index 0 are not supported by this dashboard linking mode.

Match configured limits to the DSP block limits. Changing .env requires recreating the container. Actual addresses and credentials should remain in ignored local files.

Environment mapping fields supply defaults only when no saved settings file exists. Dashboard changes are saved separately and survive image updates. The Docker entrypoint initializes data-directory ownership and then drops to the configured non-root service user.

Development

Requires Node.js 22 or newer (Docker uses Node.js 24).

cp .env.example .env
# Edit DSP_HOST before connecting to hardware.
npm start
npm test

Tests cover Telnet negotiation and fragmented replies, read-only startup behavior, all six main writes, independent sub control, invalid input, partial failures, serialized operations, and timeouts.

Architecture

Phone browser → Node.js HTTP server on Unraid → Tesira Telnet/TTP.

The backend serializes operations over one persistent Telnet session, with TCP_NODELAY enabled. On a timeout or disconnect it discards the session, preventing a late reply from satisfying a later command. Subsequent operations reconnect without automatically replaying writes. State uses periodic reads rather than subscriptions in this version. A main update uses six acknowledged per-channel commands followed by actual level reads.

Access and troubleshooting

This version has no login and is intended for a trusted local network only. Do not forward the dashboard or DSP Telnet ports to the internet. Telnet traffic is unencrypted.

  • Read logs: docker logs --tail 100 tesira-web-control
  • Verify the DSP address and that Telnet is enabled.
  • Check that the container can route to the DSP's control network on TCP port 23.
  • A channelIndex error means the block/channel mapping is wrong.
  • A level-limit error means the requested value is outside the DSP's limits.
  • For a partial update, inspect all main channel values before retrying.

See protocol verification and Unraid operations.

Biamp Tesira Text Protocol reference.

Independent project; not affiliated with Biamp.

License

MIT · Copyright 2026 Matt Clausen.

Media gallery

Requirements

Biamp Tesira DSP with Telnet enabled and network access to its control interface. Linux amd64 image.

Related apps

Details

Repository
ghcr.io/clausefoto/tesira-web-control:beta
Last Updated2026-10-23
First Seen2026-10-23

Runtime arguments

Web UI
http://[IP]:[PORT:8088]
Network
bridge
Shell
sh
Privileged
false

Template configuration

WebUI portPorttcp

HTTP dashboard port.

Target
8088
Default
8088
Value
8088
AppdataPathrw

Stores saved dashboard settings. Do not use the source checkout directory for a new installation.

Target
/data
Default
/mnt/user/appdata/tesira-web-control/config
Value
/mnt/user/appdata/tesira-web-control/config
DSP addressVariable

Required: your Tesira control-network IP address or hostname.

Target
DSP_HOST
DSP Telnet portVariable

Tesira Telnet port.

Target
DSP_PORT
Default
23
Value
23
Main instance tagVariable

Initial main-level instance tag. Case sensitive. Saved dashboard settings take priority.

Target
MAIN_TAG
Default
Level5
Value
Level5
Main channelsVariable

Initial number of main channels, 1 through 32; controls channels 1 through N.

Target
MAIN_CHANNELS
Default
6|1|2|3|4|5|7|8|9|10|11|12|13|14|15|16|17|18|19|20|21|22|23|24|25|26|27|28|29|30|31|32
Value
6
Gang main channelsVariable

Initial dashboard linking: true sets channels together; false exposes individual sliders.

Target
MAIN_GANG
Default
true|false
Value
true
Subwoofer instance tagVariable

Initial subwoofer instance tag. Case sensitive. Saved dashboard settings take priority.

Target
SUB_TAG
Default
Level4
Value
Level4
Subwoofer channelsVariable

Initial number of subwoofer channels, 1 through 32.

Target
SUB_CHANNELS
Default
1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20|21|22|23|24|25|26|27|28|29|30|31|32
Value
1
Gang subwoofer channelsVariable

Initial dashboard linking for the subwoofer channels.

Target
SUB_GANG
Default
true|false
Value
true
Main minimum dBVariable

Minimum allowed main volume.

Target
MAIN_MIN_DB
Default
-24
Value
-24
Main maximum dBVariable

Maximum allowed main volume; match your DSP block limits.

Target
MAIN_MAX_DB
Default
12
Value
12
Subwoofer minimum dBVariable

Minimum allowed subwoofer volume.

Target
SUB_MIN_DB
Default
-100
Value
-100
Subwoofer maximum dBVariable

Maximum allowed subwoofer volume; match your DSP block limits.

Target
SUB_MAX_DB
Default
12
Value
12
App user IDVariable

Non-root UID that owns saved settings.

Target
PUID
Default
99
Value
99
App group IDVariable

Non-root GID that owns saved settings.

Target
PGID
Default
100
Value
100