433 MHz

Homey is capable of sending and receiving 433 MHz and 868 MHz radio-signals for controlling remote appliances like wireless switches and thermostats.

Transmitting and receiving radio-signals requires a signal definition. This signal definition contains all elements necessary for Homey to properly receive and transmit radio signals.

Developing apps for radio controlled devices requires knowledge of data-encoding and signalling.

The homey-rfdriver library implements the basic functionality needed for all 433 MHz apps and implements a higher level interface that you can use to control 433 MHz devices. Install homey-rfdriver with the following command:

npm install homey-rfdriver

Read the RFDriver documentation at https://athombv.github.io/node-homey-rfdriver.

In order to use 433 MHz or 868 MHz signals your app will need the homey:wireless:433 or homey:wireless:868 permissions. For more information about permissions read the permissions guide.

You can view a working example of a Homey App that uses 433 MHz at: https://github.com/athombv/nl.klikaanklikuit-example

What are signals?

Signals are block-wave data signals carried over the air using an electromagnetic carrier on a given frequency. Homey can communicate on 433 MHz and 868 MHz frequency bands.

Radio modulation

An electromagnetic field has the ability to change in amplitude (signal strength) and frequency. These characteristics can be used to modulate a data signal. When the amplitude of an electromagnetic field is used to represent a high or low state it is called 'amplitude shift keying' (ASK). When a change in frequency is used to modulate a signal it is called 'frequency shift keying' (FSK).

There is also a variation on ASK modulation used by most 433 MHz devices called 'on-off keying' (OOK). Instead of defining two amplitude levels for the high and low states, OOK modulation only uses a high state amplitude level. The low state amplitude level is represented by the absence of the carrier. This is a very easy and cheap way of modulating radio signals as it only requires a few hardware components that can generate and toggle an electromagnetic carrier.

Receiving

Receiving electromagnetic waves depends on the antenna and filtering that is used. Antennas are designed to operate at a certain frequency, this prevents the reception of noisy and unwanted signals. In our case we only want to receive on the 433 MHz and 868 MHz bands, for which Homey contains two different antennas. Unfortunately using two separate antennas is not enough to prevent the reception of noise and unwanted signals. To ensure that a device only receives signals within a specific frequency band, it is important to filter out incoming signals at other frequencies.

However, in practice devices often use a somewhat deviated carrier-frequency (e.g. 433.89MHz). To ensure that Homey is able to listen to these deviating frequencies, it's receiving frequency band has been broadened by 325Khz. This results to a frequency band ranging from 433.76MHz to 434.08MHz for 433 MHz signals and 868.14MHz to 868.46MHz for 868 MHz signals.

Homey can only listen to devices with radio-frequencies that are within its frequency band

Data encoding

To convert a received block-wave into usable data, we have to decode this wave. To do this, we have to define how the data is represented in the wave. This depends on the encoding mechanism a device uses. Some device manufacturers develop their own encoding mechanisms, while others use pre-defined standards. These encodings can be edge-based (eg manchester) or duration based (eg X10). Homey can be configured to operate in both modes.

Signal definition

In order to do this, Homey needs to know the details of the protocol used. This description is called the signal definition. All signal definitions consist of two kind of properties, encoding-specific properties, and radio-specific configuration properties. Homey apps need to register their signal definition with the Homey Signal Manager. The Homey Signal Manager receives all incoming raw transmissions and attempts to match these block-waves to a registered signal definition. When an incoming signal matches a registered signal definition, the signal is automatically decoded and the contained data is routed to the corresponding app. To transmit, data travels the reverse path which means the data is encoded using the same signal definition and then transmitted.

The signal definition contains all the necessary attributes for sending and receiving signals.

Obtaining a signal

It is possible to make Homey record raw data for a short period of time using the devtools, read the devtools guide for more information.

Using signals in your App

Signals should be defined in your App Manifest, under .homeycompose/signals/<frequency>/<signal_id>.json, where frequency is either 433 or 868.

/.homeycompose/signals/433/klikaanklikuit.json
{
  "sof": [275, 2640], // Start of frame
  "eof": [275], // End of frame
  "words": [
    [250, 275, 250, 1250], // 0, or LOW
    [250, 1250, 250, 275] // 1, or HIGH
  ],
  "interval": 10000, // Time between two subsequent signal repetitions
  "sensitivity": 0.5, // between 0.0 and 0.5
  "repetitions": 20,
  "minimalLength": 32,
  "maximalLength": 36
}

Before your app can use this signal definition, it must be registered:

/app.js
const Homey = require('homey');

class App extends Homey.App {
  async onInit() {
    // create & register a signal using the id from your signal manifest
    const mySignal = this.homey.rf.getSignal433("my_signal");

    // start listening to data by enabling receive
    await mySignal.enableRX();

    // on a payload event
    mySignal.on("payload", function (payload, first) {
      console.log(`received data: ${payload} isRepetition ${!first}`);
    });

    // on a command event
    mySignal.on("cmd", function (cmdId, first) {
      console.log(`received command: ${cmdId} isRepetition: ${!first}`);
    });

    // stop listening to data by disabling receive
    await mySignal.disableRX();

    // transmit the bits 01011001
    await mySignal.tx([0, 1, 0, 1, 1, 0, 0, 1]);

    // transmit predefined command
    await mySignal.cmd("ONOFF");
  }
}

module.exports = App;

Please only register a signal if there are devices any paired, because receiving signals is quite performance intensive.

Signal requirements

A signal has to meet certain requirements in order to guarantee a proper flow of sending and receiving signals. For example, if a signal is to long, it could block other apps from sending their signals. The table below shows the signal requirements.

Signal characteristic

Description

Minimal value

Maximal value

Converted time-intervals

Number of time-intervals that is used to generate the signal

1

256

Signal duration

The total duration of a signal that is being sent

5us

1s

Transmitting

After a signal definition has been made it can be used to transmit or receive data. Data is encoded based on a signal definition which at the end is nothing more than an array of time-intervals. The Homey Signal Service receives the array with time-intervals, configures the radio with the appropriate settings and generates the signal.

Receive-after-transmit

Sometimes data only needs to be requested from a device. A request message is sent to the device and the device immediately response with the requested data. In order to receive these responses properly the radio has to switch to receive mode immediately after sending the request. With the rxTimeout attribute a receive timeout can be configured. The radio stays in receive mode for the configured time in milliseconds.

The Radio-controller cannot handle time-interval arrays larger then 256 intervals

Receiver configuration

The table below shows the radio configuration used by the 433 MHz and 868 MHz receivers. The receiver's filter bandwidth in listening mode for both 433 MHz and 868 MHz can not be changed by a developer since it is shared by other Homey apps. Changing the filter bandwidth could lead to an unstable reception of these other signals.

433 MHz configuration

Attribute

Value

Carrier frequency

433890000Hz

Channel spacing

325000Hz

BaudRate

12004Bd

Modulation

ASK

868 MHz configuration

Attribute

Value

Carrier frequency

868300000Hz

Channel spacing

325000Hz

BaudRate

12004Bd

Modulation

ASK

Creating a signal

A signal definition consists of two types of properties; signal encoding properties and radio configuration properties. The first part specifies the characteristics of the data encoding of a signal whereas the radio part specifies the required radio configuration to receive the signal.

The image below shows a repeating signal captured by a logic-analyzer from a KlikAanKlikUit remote. This signal will be used as an example throughout the article.

Red: start-of-frame Yellow: word 0 Green: word 1 Blue: end-of-frame Purple: interval

The accompanying signal definition would therefore become:

/.homeycompose/signals/433/klikaanklikuit.json
{
  "sof": [275, 2640], // Start of frame
  "eof": [275], // End of frame
  "words": [
    [250, 275, 250, 1250], // 0, or LOW
    [250, 1250, 250, 275] // 1, or HIGH
  ],
  "interval": 10000, // Time between two subsequent signal repetitions
  "sensitivity": 0.5, // between 0.0 and 0.5
  "repetitions": 20,
  "minimalLength": 32,
  "maximalLength": 36
}

The table below shows the minimum, maximum and default values of the encoding properties that can be used in the Homey signal definition.

Attribute

Description

Min.

Default

Max.

Type

Unit

agc

AGC pulses

5us

-

32767us

Array of integers

Microseconds

sof

Start-of-frame

5us

-

32767us

Array of integers

Microseconds

words

Words

5us

-

32767us

Array of integers Array

Microseconds

eof

End-of-frame

5us

-

32767us

Array of integers

Microseconds

interval

Interval

5us

5000us

32767us

Integer

Microseconds

manchesterUnit

ManchesterUnit

5us

-

32767us

Integer

Microseconds

minimalLength

Minimal payload length

1

1

Infinity

Integer

-

maximalLength

Maximal payload length

1

Infinity

Infinity

Integer

-

prefixData

Prepended data

0

-

words.length

Array of Integers

-

postfixData

Suffixed data

0

-

words.length

Array of Integers

-

cmds

Static commands

-

-

-

String => Integer Array Object

-

toggleSof

Toggled SOF

5us

-

32767us

Array of integers

Microseconds

toggleBits

Toggle bit indexes

0

-

words.length

Array of Integers

-

sensitivity

Sensitivity

0.0

0.3

0.5

float

-

packing

Packing

-

false

-

Boolean

-

txOnly

Disable receiving

-

false

-

Boolean

-

Automatic Gain Control pulse (AGC)

The AGC attribute defines the synchronisation sequence of a signal in time-intervals. This part of the signal never changes and is used by most devices to properly configure the gain of the radio receiver, before the data arrives. The sequence is defined by an array of time-intervals in microseconds. The AGC pulse is ignored when receiving, but added in transmitted signals.

It is also possible to use Manchester encoding. In that case the agc-array has to be filled with 1's and 0's rather then using time-intervals. Each 1 is replaced by a ManchesterUnit high interval and each 0 is replaced by a ManchesterUnit low interval. This interval can be defined in the ManchesterUnit attribute.

Start-of-frame (SOF)

The start-of-frame attribute defines the preamble sequence of a signal in time-intervals. This part of the signal never changes and is used by most devices to detect an incoming signal. The sequence is defined by an array of time-intervals in microseconds

The start-of-frame definition in the example above starts with a high-state interval of 275 microseconds followed by a low-state interval of 2640 microseconds. The sof is shown in the signal image indicated in red.

When using Manchester encoding the word-array has to be filled with 1's and 0's rather then using time-intervals.

Words

The words attribute contains one or more words. Each word defines a sequence of high and low time-intervals depending on the type of encoding that is used. Most devices use single-level encoding where one word defines the 1 bit and the other word defines the 0 bit. In case of multi-level encoding the bitmask increases from one bit to multiple bits. Each bit combination (00, 11, 10, 01) then refers to a particular word.

In the above example, two words are defined. The 0 word indicated in yellow corresponds to a 0-bit. The 1 word indicated in green corresponds to a 1-bit. Therefore, the data that has been sent in the example will be 00111111010001010100110110010000 summing up to 32 bits. In the 'klik-aan-klik-uit' app these bits are further split into multiple parts representing the homecode, unitcode and dim/onoff value.

When using Manchester encoding the word-array has to be filled with 1's and 0's rather then using time-intervals.

Data is sent and received using an array of binary (bit) values. Each bit (or bits when using multi-level encoding) refers to one of the words defined in the signal definition. When sending data the array of bits gets converted to the corresponding words.

End-of-frame (EOF)

The end-of-frame attribute defines the end-sequence of a signal. This part of the signal never changes. Make sure to specify minimalLengthWhen the EOF (partially) overlaps with the words, as this increases the amount of proper matches. When looking at the example, the end-of-frame consists of only one 275 microseconds interval. This is clearly shown in the signal-image indicated in blue.

When using Manchester encoding the eof-array has to be filled with 1's and 0's instead of a time-interval.

Interval

The interval attribute defines the time-interval between subsequent signals. The value is specified in microseconds.

ManchesterUnit

This time-interval is used when Manchester encoding is enabled. Instead of defining words in time-intervals, the words need to be defined in bits (1's and 0's). A word like [1, 0] with a Manchester unit time-interval of 100 microseconds gets encoded into a high signal of 100 microseconds and a low signal of 100 microseconds.

MinimalLength

The minimalLength attribute defines the minimal length of a signal in words. Sometimes devices use varying signal lengths depending on the size of the payload.

MaximalLength

The maximalLength attribute defines the maximal length of a signal in words. Some devices use varying signal lengths depending on the size of the payload.

PrefixData

The PrefixData attribute can be used to specify words that have to be added in front of each payload before transmission. When specified, incoming payloads are checked for these prefix-words, and only upon a match, the words will be stripped and the payload without prefix will be delivered to the Homey app. When transmitting data, this prefix is added to each payload as well.

PostfixData

The PostfixData attribute can be used to specify words that have to be appended after each payload before transmission. When specified, incoming payloads are checked for these postfix-words, and only upon a match, the words will be stripped and the payload without postfix will be delivered to the Homey app. The words are also appended to each payload before transmitting as well.

Commands

Sometimes, devices have a static set of commands and do not include any dynamic data such as an address. In these cases, the cmds attribute can be used to predefine all commands. This property consists of an object that maps commands (specified as identifier string) to an actual payload array (excluding prefix/postfix data).

Toggle SOF

Some signals use toggle bits. These toggle bits are used to differentiate between multiple key presses of the same command or button, by flipping the bits upon each new transmission. Homey-Signals contain two different ways to specify this behaviour.

The toggleSOF property can be used to specify a custom SOF that is being alternated with the primary SOF. This works automatically for both receiving and sending, and adjusts the first argument of both the cmd and payload events.

Toggle Bits

Some signals use toggle bits. These toggle bits are used to differentiate between multiple key presses of the same command or button, by flipping the bits upon each new transmission. Homey-Signals contain two different ways to specify this behaviour.

The toggleBits property can be used to specify bit indexes of these toggle bits inside the payload (including prefix/postfix). This works automatically for both receiving and sending, and adjusts the first argument of both the cmd and payload events. Note: The reported payload contains unmodified data, with the toggle bits as transmitted.

Sensitivity

The sensitivity attribute defines the maximum deviation between the signal definition and the received signal. This value represents the maximal percentage signals may deviate of the definition.

Packing

When sending or receiving large amounts of data it may be more convenient to receive the data in bytes rather than bits. Enabling packing makes it possible to send and receive byte- rather then bit-arrays. Every eight bits are 'packed' into a byte and added to the byte-array. Usage of this property is discouraged when the payload length is not a multiple of eight, and impossible when the signal does not contain exactly two words.

txOnly

The txOnly attribute can be used to disable the receiving subsystem of the signal, proper usage is encouraged in order to save computing resources.

Radio Configuration

The table below shows the minimum, maximum and default values of the attributes in the signal definition

Attribute

Description

Min.

Default

Max.

Type

Unit

repetitions

Repetitions

1

10

255

Integer

-

rxTimeout

rxTimeout

0

10

255

Integer

Milliseconds

modulation.type

Modulation

-

'ASK'

-

String

-

modulation.channelSpacing

Channel spacing

58000

325000

812000

Integer

Hertz

modulation.channelDeviation

Channel deviation

5000

25000

50000

Integer

Hertz

modulation.baudRate

baudRate

1000

12004

200000

Integer

Baud (Bd)

carrier

Carrier frequency

radio specific

radio specific

radio specific

Integer

Hertz

These are the carrier frequencies for 433 MHz:

min: 433000000, default: 433920000, max: 433990000

These are the carrier frequencies for 868 MHz:

min: 868000000, default: 868300000, max: 868990000

Repetitions

The repetitions attribute defines how often the signal gets transmitted. A repetitions value of 1 means 1 transmit, 2 means 2 transmits etc.

There are three ways to set the number of repetitions, from high to low priority:

  • Signal.tx() repetitions parameter (see SDK v3 reference).

  • Signal definition repetitions-attribute (see Signal definition).

  • When non of the above are specified, it will default to 20.

The repetition behavior was aligned between different Homey products as of Homey Pro (2016—2019) v10.0.6, Homey Pro (Early 2023) v10.3.1 and Homey Bridge v85.

RxTimeout

Receiver timeout when sending requests to a device. After the data has been sent, the radio switches into receiving mode and waits for rxTimeout milliseconds for the device to respond. The same radio configuration used when sending the data is also used when waiting for the response.

Modulation

The modulation attribute defines the modulation used by the radio to modulate the signal. When no modulation attribute is provided, Homey will use the default configuration.

Type

The type attribute defines the type of radio modulation that is used by the radio. Supported values are ASK, FSK and GFSK

Channel spacing

The channelSpacing attribute defines the filter bandwidth in receive mode. This attribute is only used when rxTimeout is greater than zero.

Channel deviation

The channelDeviation attribute defines the frequency deviation when using FSK or GFSK modulation.

Baudrate

The baudRate attribute defines the symbol changes per second of the specified signal in Baud.

Carrier

The carrier attribute defines the carrier frequency used while sending a signal. Most radio-devices use the 433.92MHz and 868.3MHz as carrier frequencies. There are devices that use deviating carrier frequencies (e.g. Somfy). If no carrier attribute is defined, the default receiving carrier frequency will be used.

Last updated