---
title: tvcontroller
slug: develop/tvcontroller
docTags: 
createdAt: 2025-03-27T16:56:33.880Z
---

The *tvcontroller&#xA0;*&#x6F;bject provides a communication interface between televisions and BrightSign built-in products. This object is available as of BOS 9.0.16&#x38;**.**

Multiple instances of *tvcontroller* can access the television from multiple domains (user node application, user HTML application, etc.), or you can use multiple instances of the JavaScript object. They all access the same television hardware and they all get notified with an event when the television sends a message.

**tvcontroller IDL**

```javascript
@brightsign/tvcontroller                                                                                                                                                                                                                                                                              
[Exposed=Window]                                                                                                                                                                                                                                                                                      
interface TvController {                                                                                                                                                                                                                                                                              
  Promise<void> send(Array data);                                                                                                                                                                                                                                                                     
  attribute EventHandler onreceive;                                                                                                                                                                                                                                                                   
};                                                                                                                                                                                                                                                                                                    
                                                                                                                                                                                                                                                                                                      
[Exposed=Window]                                                                                                                                   
interface ReceiveEvent : Event {                                                                                                                   
  readonly attribute Array data;                            
};   
```

## Object Creation

To create a *tvcontroller* object, load the `brightsign/tvcontroller` module using the `require()` method and then create an instance of the *tvcontroller*:

```javascript
let tv_controller_class = require("@brightsign/tvcontroller");
let tv_controller = new tv_controller_class();
```

## TvController

Use this interface to access a television (for example, to send messages)

**send()**

```javascript
Promise<void> send(Array data)
```

**Attribute**

- `onreceive` <font color="#6554c0">EventHandler</font>:

## ReceiveEvent

Use this interface to get notified with an event when the television sends a message

**Attribute**

- `data` <font color="#6554c0">Array</font>: This is a read-only attribute

## Messages

Messages are defined in the Protobuf format. BrightSign firmware includes the JavaScript bindings of the protocol buffer messages in the firmware image. To load the messages, load the following module:

```javascript
let { messages } = require("messages_pb");
```

A single Protobuf file is used for both television to BrightSign Built-In and BrightSign Built-In to television messages, because the same messages are used both for verification and update notifications. When BrightSign updates a field (for example, to set up the volume), the television sends the same message back to BrightSign that the volume is updated. The volume can be updated with the television user interface, via remote control. BrightSign also gets that as an event from the television.

There are some exceptions:

- Brightsign Built-In doesn’t send messages back to the television to confirm acknowledgement of receipt of the request message, it only sends the requested information.
- Both sides can send `PowerSettings` message to each other. To prevent confusion with receiving a command and a acknowledgement, we have `PowerSettings` and `PowerSettingsAck `message types. `PowerSettingsAck` is sent when device gets a `PowerSettings` message and switches to the requested power mode.

This is the Proto file for the communication interface:

```javascript
syntax = "proto3";

package messages;

message WhiteBalance {
    int32 red_gain = 1;   // Red channel gain (e.g., 0 to 100)
    int32 green_gain = 2; // Green channel gain (e.g., 0 to 100)
    int32 blue_gain = 3;  // Blue channel gain (e.g., 0 to 100)
}

// Message to set the TV HDMI input.
message VideoOutputSettings {
    enum VideoOutputSelection {
        HDMI_1 = 0;
        HDMI_2 = 1;
        // Add more as needed
    }
    VideoOutputSelection selected_input = 1;
}

// There may be more PowerStatus modes in the future
enum PowerStatus {
    STANDBY = 0;
    ON = 1;
    FAST_TV_START = 2;
}

// Message to set the power status
message PowerSettings {
    PowerStatus status = 1;
}

// PowerSettingsAck message is an acknowledge to power status 
// change request.
// Sender should wait for Ack after changing PowerSettings
// via PowerSettings message, or via GPIO when waking device
// up
message PowerSettingsAck {
    PowerStatus status = 1;
}

// Whatever this value is set to, the TV must store it on their side.
// And then when the TV goes into standby using an IR command, the TV
// must send that value to the BrightSign player.
//
// PowerSettingsUpdate message is mainly to be used as a trigger 
// to enable/disable "Fast TV Start".
//
message PowerSettingsUpdate {
    PowerStatus status = 1;
}

// Message to set the power lock status
message PowerLockSettings {
    enum PowerLockStatus {
        DISABLED = 0;
        ENABLED = 1;
    }
    PowerLockStatus status = 1;
}

// Message to set or get the USB device connection.
message USBConnectionSettings {
    enum USBConnection {
        CONNECTED_TO_TV = 0;
        CONNECTED_TO_SET_TOP_BOX = 1;
    }
    USBConnection connection = 1;
}

// Message to forward the IR commands received by the TV.
message IRCommandMessage {
    uint32 code = 1;
    string encoding = 2;
}

enum Request {
    DEVICE_INFO = 0;
    VIDEO_OUTPUT_SETTINGS = 1;
    POWER_SETTINGS_ACK = 2;
    USB_CONNECTION_SETTINGS = 3;
    VOLUME = 4;
    GAMMA = 5;
    BRIGHTNESS = 6;
    CONTRAST = 7;
    WHITE_BALANCE = 8;
    IDLE_STANDBY_TIMEOUT_SECONDS = 9;
    POWER_SETTINGS = 10;
    POWER_SETTINGS_UPDATE = 11;
    POWER_LOCK_SETTINGS = 12;
}

message WifiInfo {
    string mac_address = 1; // "XX:XX:XX:XX:XX:XX"
}

message DeviceInfo {
    string mac_address = 1; // "XX:XX:XX:XX:XX:XX"
    string serial_no = 2;
    string os_version = 3; // "X.X.X.X"
    int32 hw_revision = 4; //
    WifiInfo wifi_info = 5;
}

message FirmwareUpdate {
    string file_path = 1; 
}

message FirmwareUpdateComplete {
    enum FirmwareUpdateStatus {
        SUCCESS = 0;
        FAIL = 1;
    }
    FirmwareUpdateStatus status = 1;
    string reason = 2;
}

// Command message that will be sent from the set top box to the TV.
message TvCommand {
    oneof command {
        VideoOutputSettings video_output_settings = 1;
        PowerSettings power_settings = 2;
        PowerSettingsAck power_settings_ack = 3;
        USBConnectionSettings usb_connection_settings = 4;
        IRCommandMessage ir_command = 5;
        int32 volume = 6;
        float gamma = 7;
        int32 brightness = 8;
        int32 contrast = 9;
        WhiteBalance white_balance = 10;
        Request request = 11;
        DeviceInfo device_info = 12;
        int32 idle_standby_timeout_seconds = 13;
        FirmwareUpdate firmware_update = 14;
        FirmwareUpdateComplete firmware_update_complete = 15;
        PowerSettingsUpdate power_settings_update = 16;
        PowerLockSettings power_lock_settings = 17;
    }
}
```

## Usage Examples

### Set the TV Gamma Value

In this one way communication, BrightSign makes the request and the television updates and returns the gamma value.&#x20;

`Send` takes a JavaScript array, but `encode` returns `Uint8Array`.  `Uint8Array` should be converted to `Array` using `Array.from()` before calling `send`.

`decode` also expects a `Uint8Array`, but `receive` event returns `Array`. `Array` should be converted to `Uint8Array` before calling `decode` using `Uint8Array.from()`

```javascript
let tv_controller_class = require("@brightsign/tvcontroller");
let tv_controller = new tv_controller_class();
let { messages } = require("messages_pb");

tv_controller.addEventListener("receive", (event) => {
  // Decode the binary data
  let tv = messages.TvCommand.decode(Uint8Array.from(event.detail));
  switch (tv.command) {
    case 'gamma':
      let gamma = tv.gamma;
      console.log("Gamma value is updated to: " + gamma);
      break;
    default:
      console.log("Unknown command type: " + tv.command);
      break;
  }
});

const tvCommand = { gamma: 2.3 };
// Encode the data
const bytes = messages.TvCommand.encode(tvCommand).finish();
// Send it as an Array
tv_controller.send(Array.from(bytes));
```

### Send BrightSign Device Information

In the following example, the tv\_controller is set up to send a device info, when the television requests it. The application sets up a receive event listener and waits for a request event.&#x20;

Only one request, `DEVICE_INFO`, is currently available (anything else will error). A `DEVICE_INFO` request fills the required fields and sends a message back.

```javascript
let tv_controller_class = require("@brightsign/tvcontroller");
let tv_controller = new tv_controller_class();
let { messages } = require("messages_pb");

tv_controller.addEventListener("receive", (event)=>{
  // Decode the binary data
  let tv = messages.TvCommand.decode(Uint8Array.from(event.detail));
  switch (tv.command) {
    case 'request':
      // We only have DEVICE_INFO request for now
      if (tv.request != messages.Request.DEVICE_INFO) {
        throw new Error("Request is not DEVICE_INFO");
      }

      const tvCommand = {
        deviceInfo: {
          serialNo: "1234567890",
          osVersion: "1.2.3.4",
          hwRevision: 1,
          macAddress: "XX:XX:XX:XX:XX:XX",
          wifiInfo: {
            macAddress: "XX:XX:XX:XX:XX:XX"
          }
        }
      };
      const bytes = messages.TvCommand.encode(tvCommand).finish();
      tv_controller.send(Array.from(bytes));
      break;
    default:
      console.log("Unknown command type: " + tv.command);
      break;
  }
});
```

