Skip to main content

Module Method Overview

TODO: API 2.0

The module/Companion API is primarily defined by the generic class InstanceBase<>, which is provided by @companion-module/base. Your module's code will extend that class to fill out the missing base class's methods as describe here, and you will call many of the ones provided to expose functionality into Companion.

The API can be divided into (1) exposing your module class (2) methods that get called by Companion during the life of your module (3) other methods are called by you to tell Companion how to interact with the end-users and (4) various helper classes and functions that are not part of InstanceBase<>.

Exposing your module class

The main component of this is to export your class, so that Companion can import and execute it. This should be done at the top-level of src/main.ts (if you're using the recommended file structure).

In ESM this typically this like:

export default class MyModule extends InstanceBase {
...
}

export const UpgradeScripts = [...] // If you have any upgrade scripts

Or for commonjs:

module.exports = class MyModule extends InstanceBase {
...
}

module.exports.UpgradeScripts = [...] // If you have any upgrade scripts
tip

In API 1.x, this was achieved by a call to runEntrypoint(ModuleInstance, UpgradeScripts). This is no longer supported and will need to be updated

Define the module class

TypeScript Generics

If you are not using TypeScript, you can skip this section

tip

This has changed in API 2.0, before this it was a simpler TConfig that was generic for just your module config.

The first step in creating a module is creating the module Instance class. If you are using the recommended TypeScript module template, then the module definition is in src/main.ts.

The class has a type parameter which describes many things about your module. If no type is specified, the default is:

export interface InstanceTypes {
config: JsonObject
secrets: JsonObject | undefined
actions: Record<string, CompanionActionSchema<CompanionOptionValues>>
feedbacks: Record<string, CompanionFeedbackSchema<CompanionOptionValues>>
variables: CompanionVariableValues
}

You can override each of these with concrete types, so that TypeScript can offer narrower types throughout your module.

Each page explains the structure and usage of each portion in more detail

Methods called from Companion

constructor(internal)

This class constructor is called during instantiation of the class. You should not do much here as Companion is not yet ready to interact with your module. You should only do some small setup tasks, such as creating objects/instances you need and initialising properties on the class.

Shortly after this init() will be called, when Companion is ready to interact with you.

init(config: TConfig, isFirstInit: boolean, secrets: TSecrets): Promise<void>

This is called when Companion is ready to properly run your module.

The parameters are:

  • config - the user-configuration object as provided by the user
  • isFirstInit - if this is the first time this instance of your module has been run, this will be true
  • secrets - the secrets object as provided by the user

In this method you should store the config and secrets if needed, and perform any tasks to setup any connections, or other logic that your class should be running. If you are connecting over an Ethernet connection, consider setting up the connection using TCPHelper, TelnetHelper, or UDPHelper from @companion-module/base. In the callbacks for these classes, you can set the connection status by calling updateStatus. See the Connecting to the device page for more details.

tip

Many modules simply call await this.configUpdated(config, secrets) as they need to perform the same steps during configUpdated

danger

While you should setup any connections you need to make, you must not wait for the connection to complete here. Otherwise, Companion may restart your module if it thinks that this method 'timed out'.

Also, until this method has completed, users will not be able to edit the user-configuration.

Waiting in init() is a common source of bugs, leaving users with unusable connections.

configUpdated(config: TConfig, secrets: TSecrets): Promise<void>

This is called whenever the user updates the user-configuration of the module.

In this you should often destroy any existing connections, and restart them from the new user-configuration

destroy(): Promise<void>

This is called as part of stopping your module.

In this you should gracefully terminate any connections, cleanup any timers and generally ensure nothing will be leaked.

This is the last method that is called for your module when it is no longer needed.

getConfigFields(): SomeCompanionConfigField[]

This is called whenever the user goes to edit the user-configuration.

The return object of this method is an array of input-field definitions for both the TConfig object and the TSecrets object . Input-fields of the type 'secret-text' are automatically assigned to the TSecrets object; the rest will go into the TConfig object.

tip

Not every field of your config/secrets object needs to be associated with an input-field. For example, if you want to store some internal state that persists between sessions, it can be added to the config object and saved with a call to saveConfig.

Methods you call directly

There are many more methods than are described here, as they are relevant to a certain area of module functionality, and are described properly on those pages.

This list describes some common utilities

log(level: LogLevel, message: string): void

This will write a message to the Companion log from your module

updateStatus(status: InstanceStatus, message?: null | string): void

Call this to update the connected-status of your module. (Updates the status of your module shown on the Connections page.)

Provide one of the defined status values and an optional message which will be shown when hovering over it.

Action/Feedback/Variable/Preset definitions

See the corresponding pages, linked below, for the appropriate API calls.

Further Reading