Skip to content

Module development 101

Julian Waller edited this page Apr 23, 2023 · 4 revisions

Developers Guide. Ish.

With your environment setup, it is time to start looking at modules.

Companion uses plug-ins to expand its capabilities, we call these plug-ins modules. For every device you can control with Companion there is a "module", which is both a Javascript and Companion term.

Changing existing modules

When you want to make changes to an existing module, you need to fork the module's repository. This gives you somewhere to store your changes, so that you can open a request for them to be merged into the official version.
You can find the GitHub repository for each module by searching here, there is a fork option in the top right of each module page.
You can then clone this version into your companion-module-dev folder.

Creating a new module

With over 250 published modules, often you'll want to use another module's code as your base. First you'll need to create a directory to develop your module.

Before you start, make sure there isn't already a module for the same device here. Perhaps there is one that is for a similar device which uses the same protocol?

Make a directory companion-module-mymanufacturer-myproduct inside your companion-module-dev. We follow a mymanufacturer-myproduct naming scheme, try to think of what is most appropriate for your device.
Are there other similar device by the manufacturer that use the same protocol that the module could support later on? If so try and name it to more easily allow for that.

You now need to decide if you want to start from scratch, or start with the code from another module. Github provides a download as zip option, so you can download either the template or another module (the generic modules are often a good starting point). Extract the zip to the folder you created.

Note: By using another module as a base, you could inherit some subtle misconfigurations or deviations they have made from our recommendations. The guide should still make sense, but may not be a perfect match.

In a shell inside the folder, you should run the following:

  1. yarn This will install any dependencies needed by the module.

In your IDE of choice, you should start by editing the name of the module to match what yours is called. The search feature is really helpful for this!

Now have a look around and see what you can figure our from the code. These other pages will help explain some of the functionality that the module exposes to users:

What makes up a module

There are a few files that make up every module. To get an overview of what these are, please see File Structure.

The Module source code

While you can handle all your module's stuff in one big file, we strongly recommend splitting it across several files, but it's up to you.
When the user adds an instance in Companion, it instantiates the module. This will start your module in a new process, and do some basic setup with Companion.

There are various tasks to do to get a working module, which can be divided in several categories:

  1. Base module implementation
  2. Providing functionality to the user
  3. The code behind all that stuff

Base module implementation

When your module is started, first the constructor will be called, followed by your upgrade scripts and then the init method.
Your constructor should only do some minimal class setup. It does not have access to your instance config, so cannot be used to start doing things.

Inside of the init method you should setup the connection to your device and get everything working ready for actions and feedbacks to start being used.

When the module gets deleted or disabled the destroy function is called. here you should clean-up whatever you don't need anymore. Make sure to not leave timers running, as that can cause performance problems in companion as the leaked timers start piling up!

Providing functionality to the user

Most (so far all) modules do want to provide some interaction with the user. The possible items are stored in json objects. This splits up in several categories.

Printing to log

While developing you might want to print some info or variables to the console or the in companion log. The below commands will help you do just that:

For printing to console, if you launch through terminal:

  • console.log('your data/message');

And if you want it in the log in the web interface, see the log method.

Sharing your code

Once you are getting near being done you need to ask the core developers in the #module-development group on (Bitfocus Slack) to create a repository for your module (mention brand and product).
You don't need to wait for it to be created to continue, but you will before your module can be included in the beta builds. Once it has been created, you should run this in a shell inside your module folder (adjusting the url to match your new github repository):

  1. git remote add origin https://github.com/bitfocus/companion-module-mymanufacturer-myproduct.git
  2. git push origin HEAD:main

Once you're satisfied that your module works and you've tested it, you're at a point that the core developers must decide if its time to include this module in the companion core. Ask us on slack (Bitfocus Slack), and once we decide to add it, you should give it a test in the beta builds to make sure it is all still working.

If you want to change something in the module after this, you need to do your changes, commit it to the repository and ask again in slack for the updates to be included.

Testing

In any case, your module should be tested throughout at different stages of its life.
You should check the compatibility to the Companion core, especially to different versions of the configuration fields. Some users may not have used Companion in a long time and their configuration file might look different then what you expect.
And last but not least you should check all your actions with all the options and feedbacks and whatever with the real device (as much as possible). Most bugs we find are typos, which would have easily been detected be complete testing. Also please don't rely on simulations where possible, often the real device reacts differently than the simulator.

Questions? Reach out on SLACK! :)

Clone this wiki locally