Modbus is a simple communication protocol, often used to integrate HVAC equipment. It uses master-slave communication, when several devices can be connected to the common bus, each must have a unique Slave ID, and the master device always queries the individual slave devices that respond to it.
In most cases, TapHome is used in the mode where the Core control unit is Modbus Master, and the connected devices are Modbus Slave. This is set in the Hardware section → Modbus RTU or Modbus TCP. However, it is also possible to use the opposite direction, when TapHome Core provides some other superior system with information about its devices. It is defined in section Expose devices → Modbus RTU or Modbus TCP.
Modbus can communicate through different physical layers:
Modbus defines 4 types of registers:
| Register | Code | Access | Size | Function Codes |
|---|---|---|---|---|
| Holding Registers | H | Read-write | 16-bits | Read: 03, Write multiple: 16 (0x10) |
| - Write Single Holding | SH | Read-write | 16-bits | Write single: 06 |
| Coil (Discrete Output Coils) | C | Read-write | 1-bit | Read: 01, Write multiple: 15 (0xF) |
| - Write Single Coil | SC | Read-write | 1-bit | Write single: 05 |
| Discrete Input Contacts | D | Read-only | 1-bit | Read: 02 |
| Analog Input Registers | A | Read-only | 16-bits | Read: 04 |
The register number is 16 bits, that is, it can have a value from 0 to 65535. Operations can be performed on the registers:
Some Modbus implementations add additional commands: report slave id, bit masking, write and read at once, etc., but these are not supported by TapHome.
Information about what is stored in which register and in what format is part of the equipment documentation provided by the equipment supplier or manufacturer. An example of Modbus documentation from a Modbus device supplier:

Register type C (Coil), index 58, since it has only 2 values (open / closed) and allows in addition to reading and writing, the appropriate type of TapHome device is Digital output.
Accelerated instructions for integrating a Modbus device into TapHome
This documentation is intended for the scenario where the TapHome Core control unit is a Modbus master, and the physical devices that are added to the Hardware → Modbus RTU / TCP section are Modbus slaves.
Hardware → Modbus RTU: devices are connected on some BUS, the basic parameters of RS485 transmission are defined, such as baudrate, parity, stop bits, or whether the data is ASCII or binary. Only devices with the same communication settings can be connected on this bus. Also, correct communication can only work if the A and B cables are connected correctly. Hardware → Modbus TCP: devices are connected on the same LAN as the Core control unit. One TCP port is defined, which is common to all devices connected to this interface.
An interface can contain one or more modules, which in most cases cover communication with the entire physical device. From a configuration point of view, the Module defines the unique Slave ID of the connected device for Modbus RTU, and additionally the IP address for Modbus TCP.
Represents a specific control element or sensor in the TapHome system. It must always be part of one parent Module.
5 air conditioning units connected on one bus, use a common Modbus RTU interface, which defines the bus port, baudrate, and other communication parameters. The interface contains 5 modules, each of which represents one air conditioning unit with a unique Slave ID. Each module has defined devices under it, such as a thermostat, cooling / heating mode, fan power or tilting of the slats. Individual devices have defined commands for reading and/or writing Modbus values.
Supported devices:
TapHome devices communicate with physical Modbus devices using scripts.
Viac informácií o skriptovacom jazyku, predovšetkým sekcia
Bit operations
For communication with Modbus devices, scripting sections are defined on them:
MODBUSR (Modbus Read)Function for reading register from Modbus. Depending on the data type, it can be 1 register (for 16-bit data types), 2 registers (for 32-bit data types), or more registers (for String data types).
MODBUSR(register_type, register_address, data_type, [OPTIONAL: number_of_characters if data_type=String])
Example: MODBUSR(H, 20, Int16)/100
Read the H register number (or address) 20, and interpret it as a 16-bit Integer (a whole number with a +- sign). Finally, divide this value by the number 100 (shift the decimal point 2 places to the left).
The registry address can also be entered in hexadecimal format, e.g. the value 20 can be written as 0x14.
MODBUSW (Modbus Write)MODBUSW(register_type, register_address, data_type, value_to_write)
Example: MODBUSW(H, 20, Int16, Te * 100)
In the register H with address 20, write the value of the variable Te multiplied by the number 100 (shifting the decimal point by 2 to the right).
MODBUSWNE (Modbus Write if Not Equal)The same as MODBUSW with the difference that it reads the value from the register before writing, and writes it only if the written value is different from the read one. The whole operation takes longer, and its typical use is when setting the properties of a Modbus device, where the configuration is written to the EEPROM memory with a limited number of writes.
The functions MODBUSR, MODBUSW and MODBUSWNE can only be used in Modbus scripts. If used in other scripts, they are considered an error.
The contents of the registers are defined in the modbus table. Since the size of one Modbus register is 16 bits, 16-bit Int16 or UInt16 values are most often used, and decimal places are counted down by divisions of 10 or 100. But some Modbus devices also use 16-bit registers with floating-point numbers (Float), or they have a changed bit order (big endian, little endian), they write one number in two registers (32 bit variations). Sometimes the easiest way to find out the correct data type is to use the utility directly in the TapHome application (Manual Operations), where you can load 1 or more registers and dynamically switch the data type.
Int16: -32,768 to 32,767Uint16: 0 to 65,535Int32: -2,147,483,648 to 2,147,483,647Uint32: 0 to 4,294,967,295Float: IEEE 754 Single precision floating pointBool: 0 = false, 1 = trueBigEndianInt16 = Int16LittleEndianInt16BigEndianUint16 = Uint16LittleEndianUint16BigEndianInt32 / BigEndianInt32ByteSwapLittleEndianInt32 / LittleEndianInt32ByteSwapBigEndianUint32 / BigEndianUint32ByteSwapLittleEndianUint32 / LittleEndianUint32ByteSwapBigEndianFloat / BigEndianFloatByteSwapLittleEndianFloat / LittleEndianFloatByteSwapString: BCD format can also be used, thanks to the functions TOBCD() and FROMBCD()Each device in the Modbus interface has a defined Poll Interval attribute. This determines how often the TapHome control unit should poll for new Modbus device values. Modbus communication is of the Master-Slave type, and thus information from the Modbus device can reach TapHome only when TapHome requests it. The longer the Poll Interval, the later the value in TapHome is refreshed. Too short a Poll Interval may mean that TapHome will be unnecessarily burdened by obtaining unnecessary values, and may not have time to serve all devices within the given time interval. For example, with Modbus RTU and lower Baud Rate speeds, e.g. 9600, one query / response can take tens of ms. For thermometers, in most cases, an interval of 15000ms (15s) is sufficient, for buttons, on the contrary, as little as possible, e.g. 50 ms. Some Modbus devices expect the master to periodically write the current value to the register. This is what the Periodic Write attribute is for.
In some scripts it is possible to define an error / warning / information on the device, based on the information read from the device's Modbus registers. These messages are displayed in TapHome in the same way as internal TapHome error messages. Optionally, a numeric error code can be added to the error message if practical for servicing the Modbus device.
Only one error message with no code or only one error message per error code can be defined on the device.
ADDERROR(), ADDWARNING(), ADDINFO()
ADDERROR([Optional: custom_code], text)
Example: in the Read Script section of the Analog Output device there is a code:
ADDERROR("Error without code");
ADDWARNING("Warning without code");
ADDINFO("Info without code");
ADDERROR(1, "Error with code");
ADDWARNING(1, "Warning with code");
ADDINFO(1,"Info with code");
...which is reflected on the device by messages:

In addition to a value (or multiple values, such as a Thermostat) from a connected Modbus device, TapHome modules and devices can also read service attributes or perform service actions. These are then not accessible on the desktop for other users of the system, but serve only for more detailed information about the Modbus device, without unnecessarily overloading the system with a large number of variables and actions.
Service attributes are displayed in the service settings of the TapHome module or device. Typically, they are used to display information about the device, such as Model, Serial Number, Firmware Version, Hardware Version, Time since last reboot, etc. This is useful information from the point of view of servicing a Modbus device, but it does not make sense to create separate TapHome devices for them.
Service actions are displayed in the service settings of the TapHome module or device, at the very bottom as buttons. When pressed, they perform a preset Modbus action that writes the required information to the register. Example of use: Setting or changing the Slave ID, Replacing the filter, Setting the counter to the required value, Resetting the device and the like.
Variables defined on a module are usable in all scripts on the module and are shared with all devices assigned to that module.
Optional. Runs when the module starts. If it is filled and has not yet run, no further scripts will be allowed.
Runs every time a module is polled.
Running:
Each module can have an unlimited number of service attributes defined. The scripts are executed every time a user (with service privileges) opens the module's service settings screen in the app. They are written at the top, immediately after reading from the Modbus device.
Each module can have an unlimited number of service actions defined. The scripts are started when the user (with service privileges) opens the app on the module's service settings screen and presses one of the defined buttons with the name of the service action. Each service action is defined by its name, parameters, and execution script.
Variables defined on a device are usable in all scripts defined on that device, and are not usable anywhere outside the device. The device can store its state in them, share between its scripts, and so on.
Optional. It starts when the device starts. If it is filled and has not yet run, no further scripts will be allowed.
Runs every time the device is polled, before "Read Value Scripts".
Running:
Runs every time a device is polled.
ADDERROR(1, "Sensor not connected") command is in the Read Temperature script in the Thermostat device, the user will see an error message in the app on the thermostat with three pieces of information: Temperature, code 1, text "Sensor not connected".Each device can have an unlimited number of service attributes defined. The scripts are executed every time a user (with service privileges) opens the device's service settings screen in the app. They are written at the top, immediately after reading from the Modbus device.
Each device can have an unlimited number of service actions defined. The scripts are executed when the user (with service privileges) opens the app on the device's service settings screen and presses one of the defined buttons with the name of the service action. Each service action is defined by its name, parameters, and execution script.
It allows you to configure Modbus communication with the device without any knowledge of the Modbus protocol or how to configure it in TapHome. Pre-made templates can be found:
More info on configuring Modbus communication using templates
A practical tool for quick initial verification of the Modbus table. Allows:
A common practice when setting up communication with a Modbus device is that the factory default Slave ID is other than 1, and it is not easy to work out the correct number. That's what this utility is for. It can scan the specified Slave ID range by trying to read from the selected register always with the tested Slave ID.
It is located in the lower part of the Modbus module. For each register used, it lists information about:
TapHome creates a list of registers to read from and write to Modbus devices, depending on the set Poll interval. Prefetch is a process thanks to which the control unit prefetches into the buffer the values that it will need during the update. The goal is to minimize the number of requests and round trips. Prefetch is affected by 2 settings:
Prefetch can also be influenced directly from the script: If we use the SC or SH register (instead of C or H) when reading, then the value is read one register at a time during the execution of the script, and it is not pulled from the cache memory. Similarly, when writing, if we use SC or SH register (instead of C or H), the value is written one register at a time and by another modbus function. Modbus protocol supports 4 writing functions: writing multiple H, multiple C, writing one H or one C register at a time. Attention: not all devices may support all these functions. In this way, if necessary, reading and writing can be combined together and "one at a time".
In most cases, the default value is 502, but it is possible that some devices listen on a different port.
The time after which TapHome gives up waiting for a response and reports a "Timeout" error. This means the device did not respond within the given interval.
The delay that TapHome inserts between individual requests to a Modbus device.
| Modbus Type | Default Delay |
|---|---|
| Modbus TCP | 0ms |
| Modbus RTU | Based on communication speed (baud rate), typically at least 3.5 characters |
📌 Device Considerations:
Modbus ASCII is a less common standard where communication is not binary, but instead uses ASCII characters.