1. Component Overview
For a short overview of OpenMUC’s goals and features please visit our website: http://www.openmuc.org/index.php?id=11. This guide is is a detailed documentation on how OpenMUC works and how to use it.
The following picture illustrates how OpenMUC works.

All boxes seen in the picture are implemented as software modules called OSGi bundles that run independently in the OSGi environment. All modules except for the data manager are optional. Thus by selecting the modules you need you can easily create your own customized and lightweight system.
The different modules in the picture are now further explained:
-
The data manager represents the core and center of OpenMUC. Virtually all other OpenMUC modules (e.g. drivers, data loggers, servers, applications and web interface plugins) communicate with it through OSGi services. The data manager gets automatically notified when new drivers or data loggers get installed. OpenMUC applications communicate with devices, access logged data or change the configuration by calling service functions provided by the data manager. It is therefore the data manager that shields the application programmer from the details of the communication and data logging technology. What the data manager does is mostly controlled through a central configuration.
-
The channel configuration hold the user defined data channels and its parameters. Data channels are the frameworks representation of data points in connected devices. Amongst others the channel configuration holds the following information:
-
communication parameters that the drivers require
-
when to sample new data from connected devices
-
when to send sampled data to existing data logger(s) for efficient persistent storage.
The configuration is stored in the file conf/channels.xml. You may add or modify the configured channels by manually editing the channels.xml file or through the channel configurator web interface.
-
-
A driver is used by the data manager to send/get data to/from a connected device. Thus a driver usually implements a communication protocol. Several communication drivers have already been developed (e.g. IEC 61850, ModbusTCP, KNX, DLMS/COSEM). While implementing drivers for OpenMUC we also develop standalone communication libraries (e.g. OpenIEC61850, jMBus). These libraries do not depend on the OpenMUC framework and can therefor be used by any Java application. New communication drivers for OpenMUC can be easily developed by third parties.
-
A data logger saves sampled data persistently. Essentially the data manager forwards sampled data to all available data loggers if configured to do so. Data loggers are specifically designed to store time series data for short storage and retrieval times. Note that this usually means that they are not SQL-based. OpenMUC currently includes two data loggers. The ASCII data logger saves data in a human readable text format while SlotsDB saves data in a more efficient binary format.
-
If all you want is sample and log data you may not need to program an application. But if you want to process sampled data or control a device you will want to write your own application. Like all other modules your application will be an OSGI bundle. In your application you can use the DataAccessService and the ConfigService provided by the data manager to access sampled and logged data. You may also issue immediate read or write commands. These are forwarded by the data manager to the driver. The configuration (when to sample and to log) can also be changed during run-time by the application. At all times the application only communicates with the data manager and is therefor not confronted with the complicated details of the communication technology being used.
-
If your application is located on a remote system (e.g. a smart phone or an Internet server) then the data and configuration can be accessed through an OpenMUC server. At the moment we have a single server: a RESTful web service.
-
Finally the OpenMUC framework provides a web user interface for tasks such as configuration, visualization of sampled data or exporting logged data. The web interface is modular and provides a plug-in interface. This way developers may write a website that integrates into the main menu of the web interface. The web UI is mostly for configuration and testing purposes. Most companies will want to create their own individual UI.
2. Demo Framework
An easy way to start understanding OpenMUC is by running the demo framework and experimenting with it. This chapter will guide you through this process.
2.1. Demo Files
The OpenMUC demo is located in the folder "demo" inside the OpenMUC distribution archive. The "demo" folder contains the folders "projects" and "framework". The "projects" folder contains several demo software projects that can be imported into Eclipse as we will explain later. The following demo projects exist:
-
simpledemoapp - A demo app which demonstrates how to write an application that runs within the OpenMUC OSGi environment. The demo app accesses data provided by the data manager (and retrieved using the dummy driver).
-
dummydriver - A driver which provides dummy data in form of a sine wave to the OpenMUC core. Normally an OpenMUC driver implements a specific communication protocol (e.g. Modbus) that can be used by the OpenMUC data manager to get data from connected devices. The dummy driver does no communication but returns dummy data instead.
The two demo projects will be running inside the demo framework. The demo framework is located in the "framework" folder that contains the following files and folders:
-
felix - contains the Felix OSGi framework jar file. OpenMUC consists of software modules called OSGi bundles that run inside an OSGi container/framework. Different OSGi implementations exist (e.g. Apache Felix, Eclipse Equinox, Knopflerfish). The OpenMUC demo is based on the Apache Felix OSGi platform because it is very easy to use and well documented. You may use another implementation as long as it conforms to the 4.2 spec of OSGi.
-
bundle - contains all the bundles that the Felix OSGi environment will automatically run at start up.
-
conf - contains different configuration files:
-
channels.xml - the central configuration file for OpenMUC. It is read by the data manager at start up. It holds all the information on devices and channels that are known to the OpenMUC system. Parameters such as the communication address of a connected device or the data logging interval are specified here.
-
-
run-openmuc.sh - starts the framework.
2.2. Running the Demo
You can start the OpenMUC demo framework by running the Felix OSGi framework in the following way:
java -jar felix/felix.jar
For convenience you may also run OpenMUC by executing run-openmuc.sh (Linux) or run-openmuc.bat (Windows, you have to rename the file first). You may want to use the "-b" option to run the openmuc framework as a background process.
Once the Felix framework has initialized it will start all the bundles located in the folder named "bundle". In the terminal you will see the logging messages generated by the OpenMUC framework and the demo app.
The OSGi framework also starts the Felix GoGo shell (http://felix.apache.org/site/apache-felix-gogo.html). It allows you to interact with the OSGi environment on the console. Type "help" to see a list of available commands. You can stop the OSGi framework anytime by stopping the system bundle with the command "stop 0" or the shortcut ctrl+c. Type "lb" to see a list of all bundles available in the framework. The core OpenMUC bundles are:
-
OpenMUC Core - API - the interfaces and classes that form the application programming interface of OpenMUC. The API consists of two OSGi services, the DataAccessService and the ConfigService. They are implemented/provided by the data manager.
-
OpenMUC Core - SPI - the interfaces and classes that form the service providing interface. The SPI consists of the DriverService and DataLoggingService. These services are provided by the individual drivers and data loggers (that could be considered as plugins). OpenMUC applications do not need the SPI, they only depend on the API.
-
OpenMUC Core - Data Manager - The core implementation of the API. It provides the services defined in the API and it automatically detects drivers and data loggers that provide the services defined in the SPI. The separation of API and data manager allows to update the data manager during runtime without effects on other bundles that depend on the API. The separation API of SPI was done to hide the application developer from the SPI classes and interfaces that he does not need.
2.3. The Data Manager
Lets start by stopping the Simple Demo App. In the Felix GoGo shell type "lb" to see the list of the installed bundles. Check what ID the Simple Demo App has and then stop it using the stop command:
>stop <id>
With "lb" you can check again if the bundle has been stopped. The state should be "resolved" now. Though the demo application is no longer running, the data manager is still running and doing what it was configured to do. Let us take a look at the conf/channels.xml file to see what the data manager is doing.
The channels.xml file configures the driver with the ID "dummy". Every driver has a unique ID that is documented in the section on drivers. For the dummy driver a single device is configured with a device address equal to "dummy/device/address/1". The device address is a string that tells the driver the communication address of the device. This way the driver nows how to connect to the device. The syntax is driver specific. Drivers that implement a protocol on top of TCP/IP could have a syntax like <ip>:<port> for example. The dummy driver ignores that address because it does not really communicate with a device.
This configured device contains two channels. Each channel defines a data point inside the device. Both channels have a sampling interval set to 100ms. This means the data manager will ask the dummy driver every 100ms to read new values for these two channels. Since the dummy driver does not really read a device it simply returns a dummy value from a sine curve. The value is returned together with a timestamp that indicates when the driver received the given value and a flag that indicates whether the value is valid or why it could not be retrieved. A sampled value, a timestamp and a flag together form a record. The sampled record is held in memory by the data manager until it is overridden by the next sample. It can be accessed by applications by calling the getLatestRecord() function of a channel object as we will see. Samples may also be logged if the data manager is configured to do so.
Both channels in the configuration are configured with a logging interval of 8s. This means that every 8s the data manager will take the latest record and forward it to all installed data loggers for persistent storage. In the demo framework both the ASCII logger and SlotsDB a binary logger are installed. Therefor the records are stored by both loggers. The ASCII logger logs its data in the demo/framework/asciidata folder. You may now want to check if the data logging works correctly.
2.4. Demo App
We will now go through the DemoApp so you better understand the capabilities of OpenMUC. First you can start the Simple Demo App again by executing "start <id>" in the GoGo shell of the framework.
You will get an output that shows you the values which were sampled for channel1:
The DummyDriver provides some data which is read or written by the data manager. The DemoApp accesses this data via the data manager and triggers the data manager to write data to the DemoDriver.

In order to follow the code of the demo app it is convenient to import the Sample Demo App into Eclipse. Follow the instructions on the following site: http://www.openmuc.org/index.php?id=28 . Note that you have to execute "gradle eclipse" within the folder demo/projects/simpledemoapp in order to create the Eclipse project files for the demo app.
2.5. Flag Values
An OpenMUC record contains a flag indicating if its value is valid or if it is null or obsolete because of some error condition. The flag is also logged by most loggers. Each possible value of the flag enumeration has an associated integer value (i.e. code). The flag codes exist.
01: VALID
02: TIMEOUT
03: UNKNOWN_ERROR
05: DEVICE_OR_INTERFACE_BUSY
06: ACCESS_METHOD_NOT_SUPPORTED
07: NO_VALUE_RECEIVED_YET
08: CONNECTING
09: WAITING_FOR_CONNECTION_RETRY
10: DISCONNECTING
11: DRIVER_UNAVAILABLE
12: SAMPLING_AND_LISTENING_DISABLED
13: DISABLED
14: CHANNEL_DELETED
15: STARTED_LATE_AND_TIMED_OUT
16: DRIVER_THREW_UNKNOWN_EXCEPTION
17: COMM_DEVICE_NOT_CONNECTED
18: DRIVER_ERROR_CHANNEL_ADDRESS_SYNTAX_INVALID
19: DRIVER_ERROR_CHANNEL_WITH_THIS_ADDRESS_NOT_FOUND
20: DRIVER_ERROR_CHANNEL_NOT_ACCESSIBLE
21: DRIVER_ERROR_CHANNEL_TEMPORARILY_NOT_ACCESSIBLE
22: DRIVER_ERROR_CHANNEL_VALUE_TYPE_CONVERSION_EXCEPTION
23: INFEASIBLE_TO_SAMPLE_CHANNEL_GROUP_IN_ONE_REQUEST
24: DRIVER_ERROR_SAMPLING_GROUP_NOT_FOUND
25: DRIVER_ERROR_SAMPLING_GROUP_NOT_ACCESSIBLE
26: DRIVER_ERROR_CHANNEL_NOT_PART_OF_SAMPLING_GROUP
27: CANNOT_WRITE_NULL_VALUE
28: DRIVER_ERROR_READ_FAILURE
29: CONNECTION_EXCEPTION
2.6. The WebUI
Now we want to see the data which are actually sampled by the data manager.
-
Run the demo via run-openmuc.sh. When the demo is running open your browser and go to https://localhost:8889/ to show OpenMUC’s web interface.
-
Login with Username: admin and Password: admin
-
Click on the Data Plotter node which you will find under Applications
-
Click on the Live Plotter tab
-
Set Refresh to 1 second
-
Select channel1
-
Click on Plot Data
Now the live plotting of channel1 starts.
3. Configuration
The conf/channels.xml file is the main configuration file for OpenMUC. It tells the OpenMUC framework which channels it should log and sample. It contains a hierarchical structure of drivers, devices and channels. A driver can have one or more devices and devices can have one or more channels. Following listing shows a sample configuration to illustrate the hierarchical structure. The driver, device and channel options are explained afterwards.
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<configuration>
<logger>loggerId</logger>
<driver id="driver_x">
<!-- driver options -->
<device>
<!-- device options -->
<channel>
<!-- channel options -->
</channel>
<channel>
<!-- channel options -->
</channel>
</device>
</driver>
<driver id="driver_y">
<!-- driver options -->
<device>
<!-- device options -->
<channel>
<!-- channel options -->
</channel>
</device>
<device>
<!-- device options -->
<channel>
<!-- channel options -->
</channel>
</device>
</driver>
</configuration>
driver id="drivername"> replace drivername with driver you want to use like "modbustcp" or "m3b".
Options | Mandatory | Values | Default | Description |
---|---|---|---|---|
id |
yes |
string |
- |
Id of the driver |
samplingTimeout |
no |
time* |
? |
Default time waited for a read operation to complete if the device doesn’t set a samplingTimeout on its own. |
connectRetryInterval |
no |
time* |
? |
Default time waited until a failed connection attempt is repeated. |
disabled |
no |
true/false |
false |
While disabled, no connections to devices on this driver are established at all and all channels of these devices stop being sampled and logged |
Device options
Options | Mandatory | Values | Default | Description |
---|---|---|---|---|
id |
no |
string |
- |
ID of the device |
deviceAddress |
yes |
string |
- |
Address for the driver to uniquely identify the device. Syntax of this address is up to the driver implementation |
description |
no |
string |
- |
Description of the device |
settings |
no |
string |
- |
Additional settings for the driver. Syntax is up to the driver implementation |
samplingTimeout |
no |
time* |
? |
Time waited for a read operation to complete. Overwrites samplingTimeout of Driver. |
connectRetryInterval |
no |
time* |
? |
Time waited until a failed connection attempt is repeated |
disabled |
no |
true/false |
false |
While disabled, no connection of this device is established and all channels of this device stop being sampled and logged |
Channel options
Options | Mandatory | Values | Default | Description |
---|---|---|---|---|
id |
no |
string |
? |
Globally unique identifier. Used by data logger implementations. The OpenMUC framework automatically generates an id if none is provided. |
description |
no |
string |
? |
Description of the channel |
channelAddress |
yes |
string |
- |
The channelAddress is driver specific and contains the necessary parameters for the driver to access |
valueType |
no |
DOUBLE FLOAT LONG INTEGER SHORT BYTE BOOLEAN BYTE_ARRAY |
DOUBLE |
Data type of the channel. Used on data logger. Driver implementation do NOT receive this settings |
valueLength |
no |
integer |
Only used if valueType == BYTE_ARRAY. Determines the maximum length of the byte array |
|
scalingFactor |
no |
double e.g.: 1.0 4.94147E-9 |
Is used to scale a value read by a driver or set by an application. The value read by an driver is multiplied with the scalingFactor and a value set by an application is divided by the scalingFactor. |
|
valueOffset |
no |
double |
0 |
Is used to offset a value read by a driver or set by an application. The offset is added to a value read by a driver and subtracted from a value set by an application. |
unit |
no |
string |
- |
Physical unit of this channel. For information only (info can be accessed by an app or driver) |
loggingInterval |
no |
time* |
- |
Time difference until this channel is logged again. -1 or omitting loggingInterval disables logging |
loggingTimeOffset |
no |
time* |
0 |
|
listening |
no |
true/false |
false |
Determines if this channel shall passively listen for incoming value changes from the driver |
samplingInterval |
no |
time* |
- |
Time interval between two attempts to read this channel. -1 or omitting samlingOffset disables sampling on this channel |
samplingTimeOffset |
no |
time* |
0 |
|
samplingGroup |
no |
string |
- |
For grouping channels. All channels with the same samplingGroup and same samplingInterval are in one group. The purpous of samplingGroups is to improve the drivers performance - if possible. |
isReadable |
no |
true/false |
false |
For information only (info can be accessed by an app or driver) |
isWritable |
no |
true/false |
false |
For information only (info can be accessed by an app or driver) |
disabled |
no |
true/false |
false |
If a channel is disabled, all sampling and logging actions of this channel are stopped |
*time: integer with suffix (ms, s, m, h) like: 300ms, 2s.
![]() |
if you don’t use a suffix, then ms is automatically used |
Default Data Logger
You can define a default data logger by adding a logger element with the id of a data logger to the configuration. If available, that data logger is used to read logged values. The ids of data loggers shipped with the OpenMUC Framework are defined in the "Data Loggers" chapter. If no logger with the defined id is available, or the logger element is missing from the configuration, an arbitrary available logger is used to read logged values. Only one default logger may be defined. If multiple logger elements exists, only the first one is evaluated.
This configuration only affects reading of already logged values. Channels are still logged by all available loggers.
3.1. Sampling, Listening and Logging
-
sampling is when the data manager frequently asks a driver to retrieve a channel value.
-
listening is when the driver listens on a channel and forwards new values to the data manager.
-
logging is when the data manager forwards the current sampled value to the data loggers that are installed. The data loggers then store the data persistently
The following examples will give you a better understanding of these three settings.
<channel>
<id>channel1</id>
<channelAddress>dummy/channel/address/1</channelAddress>
<samplingInterval>4s</samplingInterval>
</channel>
In example 1 the channel is sampled every 4 seconds which means the data manager requests every 4 seconds the current value from the driver.
<channel>
<id>channel2</id>
<channelAddress>dummy/channel/address/2</channelAddress>
<samplingInterval>4s</samplingInterval>
<loggingInterval>8s</loggingInterval>
</channel>
Example 2 extends example 1 by an additional logging. The logging interval is set to 8 seconds which means that every 8 seconds the last sampled value is stored in the database. In this case every second sampled value is stored because the sampling interval is 4 seconds. To log every sampled value the sampling interval and logging interval need to be the same.
<channel>
<id>channel3</id>
<channelAddress>dummy/channel/address/3</channelAddress>
<listening>true</listening>
</channel>
In example 3 listening instead of sampling is used. This means that the driver reports a new channel value to the data manager when the value has changed for example.
<channel>
<id>channel4</id>
<channelAddress>dummy/channel/address/4</channelAddress>
<listening>true</listening>
<loggingInterval>8s</loggingInterval>
</channel>
Example 4 extends example 3 by an additional logging.
![]() |
When listening is true and additional a sampling interval is defined then the sampling is ignored. |
4. Developing an Application
5. Drivers
5.1. Modbus (TCP/RTU)
Modbus Homepage: http://www.modbus.org
Modbus Protocol Specifications: http://www.modbus.org/specs.php
Modbus Master Simulator modpoll: http://www.modbusdriver.com/modpoll.html
Configuration Synopsis |
||
TCP |
RTU |
|
ID |
modbus |
|
Device Address |
<ip>[:<port>] |
<serial port> |
Settings |
<type> |
<type>:<encoding>:<baudrate>:<databits>:<parity>:<stopbits>:<echo>:<flowControlIn>:<flowControlOut> |
Channel Address |
<UnitId>:<PrimaryTable>:<Address>:<Datatyp> |
DeviceAddress
For TCP:
The DeviceAddress is specified by an IP address and an optional port. If no port is specified, the driver uses the modbus default port 502.
For RTU:
The DeviceAddress is specified by a serial port like /dev/ttyS0.
![]() |
The driver uses the jamod library which itself uses the rxtx library for serial communication. Therefor the librxtx-java package needs to be installed on the system. Furthermore the user needs to be in the groups dialout and plugdev |
Settings
<type> |
TCP |
<type> |
RTU |
<encoding> |
SERIAL_ENCODING_RTU |
<baudrate> |
Integer value: e.g.: 2400, 9600, 115200, … |
<databits> |
DATABITS_5, DATABITS_6, DATABITS_7, DATABITS_8 |
<parity> |
PARITY_EVEN, PARITY_MARK, PARITY_NONE, PARITY_ODD, PARITY_SPACE |
<stopbits> |
STOPBITS_1, STOPBITS_1_5, STOPBITS_2 |
<echo> |
ECHO_TRUE, ECHO_FALSE |
<flowControlIn> |
FLOWCONTROL_NONE, FLOWCONTROL_RTSCTS_IN, FLOWCONTROL_XONXOFF_IN |
<flowControlOut> |
FLOWCONTROL_NONE, FLOWCONTROL_RTSCTS_OUT, FLOWCONTROL_XONXOFF_OUT |
Example: <settings>RTU:SERIAL_ENCODING_RTU:38400:DATABITS_8:PARITY_NONE:STOPBITS_1 :ECHO_FALSE:FLOWCONTROL_NONE:FLOWCONTROL_NONE</settings>
ChannelAddress
The ChannelAddress consists of four parts: UnitId, PrimaryTable, Address and Datatyp which are explained in detail in the following table.
Parameter | Description |
---|---|
UnitId |
In homogenious architecture (when just MODBUS TCP/IP is used) In heterogeneous architecture (when using MODBUS TCP/IP and MODBUS serial or MODBUS+) Note: Some MODBUS devices act like a bridge or a gateway and require the UnitId even if they are accessed through TCP/IP. One of those devices is the Janitza UMG. To access data from the Janitza the UnitId has to be 1. |
PrimaryTable |
PrimaryTable defines the which part of the device memory should be accessed. Valid values: COILS, DISCRETE_INPUTS, INPUT_REGISTERS, HOLDING_REGISTERS |
Address |
Address of the channel/register. Decimal integer value - not hex! |
Datatyp |
Valid values: BOOLEAN, SHORT, INT, FLOAT, DOUBLE, LONG, BYTEARRAY[n] (n = number of REGISTERS not BYTES, 1 Register = 2 Bytes!) |

Valid Address Parameter Combinations
Since COILS and DISCRETE_INPUTS are used for bit access, only the data type BOOLEAN makes sense in combinations with of one of these. INPUT_REGISTERS and HOLDING_REGISTERS are used for register access. There is also a difference between reading and writing. Only COILS and HOLDING_REGISTERS are readable and writable. DISCRETE_INPUTS and INPUT_REGISTERS are read only. The following table gives an overview of valid parameter combinations of PrimaryTable and Datatyp.
Primary Table |
BOOLEAN |
SHORT |
INT |
FLOAT |
DOUBLE |
LONG |
BYTEARRAY[n] |
COILS |
ok |
x |
x |
x |
x |
x |
x |
DISCRETE_INPUTS |
ok |
x |
x |
x |
x |
x |
x |
INPUT_REGISTERS |
x |
ok |
ok |
ok |
ok |
ok |
ok |
HOLDING_REGISTERS |
x |
ok |
ok |
ok |
ok |
ok |
ok |
Primary Table |
BOOLEAN |
SHORT |
INT |
FLOAT |
DOUBLE |
LONG |
BYTEARRAY[n] |
COILS |
ok |
x |
x |
x |
x |
x |
x |
DISCRETE_INPUTS |
x |
x |
x |
x |
x |
x |
x |
INPUT_REGISTERS |
x |
x |
x |
x |
x |
x |
x |
HOLDING_REGISTERS |
x |
ok |
ok |
ok |
ok |
ok |
ok |
Examples for valid addresses:
<channelAddress>255:INPUT_REGISTERS:100:SHORT</channelAddress> +
<channelAddress>255:COILS:412:BOOLEAN</channelAddress>
Examples for invalid addresses:
<channelAddress>255:INPUT_REGISTERS:100:BOOLEAN</channelAddress> (BOOLEAN doesn't go with INPUT_REGISTERS) +
<channelAddress>255:COILS:412:LONG</channelAddress> (LONG does not go with COILS)
Function Codes (more detailed information about how the driver works)
The driver is based on the Java Modbus Library (jamod) which provides read and write access via modbus. Following table shows which modbus function code is used to access the data of the channel.
jamod Method |
Modbus Function Code |
Primary Table |
Access |
Java Data Type |
ReadCoilsRequest |
FC 1 Read Coils |
Coils |
RW |
boolean |
ReadInputDiscretesRequest |
FC 2 Read Discrete Inputs |
Discrete Inputs |
R |
boolean |
ReadMultipleRegistersRequest |
FC 3 Read Holding Registers |
Holding Registers |
RW |
short, int, double, long, float, bytearray[] |
ReadInputRegistersRequest |
FC 4 Read Input Registers |
Input Registers |
R |
short, int, double, long, float, bytearray[] |
WriteCoilRequest |
FC 5 Write Single Coil |
Coils |
RW |
boolean |
WriteMultipleCoilsRequest |
FC 15 Write Multiple Coils |
Coils |
RW |
boolean |
WriteMultipleRegistersRequest |
FC 6 Write Single Registers |
Holding Registers |
RW |
short, int, double, long, float, bytearray[] |
WriteMultipleRegistersRequest |
FC 16 Write Multiple Registers |
Holding Registers |
RW |
short, int, double, long, float, bytearray[] |
Example
<channelAddress>255:INPUT_REGISTERS:100:SHORT</channelAddress> will be accessed via function code 4.
5.1.1. Modbus TCP and Wago
![]() |
Till now the driver has been tested with some modules of the Wago 750 Series with the Fieldbus-Coupler 750-342 |
If you want to use the Modbus TCP driver for accessing a Wago device you first need to know how the process image is build. From the process image you can derive the register addresses of your Wago modules (AO, AI, DO, DI). You find detailed information about the process image in WAGO 750-342 Manual on page 46 and 47.
The following Examples are based on figure [wago]
Example 1: Read AI 2 from first (left) 472-module (Register Address 0x0001)
<channelAddress>255:INPUT_REGISTERS:1:SHORT</channelAddress>
Example 2: Read DI 3 from first (left) 472-module (Register Address 0x0003)
<channelAddress>255:DISCRETE_INPUTS:3:BOOLEAN</channelAddress>
Example 3: Write AO 1 from first (left) 550-module (Register Address 0x0000/0x0200)
For writing only the +0x0200 addresses should be used! Since the driver accepts only a decimal channelAddress 0x0200 must be converted to decimal. The resulting address would be:
<channelAddress>255:HOLDING_REGISTERS:512:SHORT</channelAddress>
Example 4: Write DO 2 from 501-module (Register Address 0x0000/0x0201)
For writing only the +0x0200 addresses should be used! Since the driver accepts only a decimal channelAddress 0x0201 must be converted to decimal. The resulting address would be:
<channelAddress>255:COILS:513:BOOLEAN</channelAddress>
Example 5: Read back DO 2 from 501-module (Register Address 0x0201)
<channelAddress>255:COILS:513:BOOLEAN</channelAddress> or
<channelAddress>255:DISCRETE_INPUTS:513:BOOLEAN</channelAddress>
5.2. M-Bus (wired)
M-Bus is communication protocol to read out meters.
Configuration Synopsis |
|
ID |
mbus |
Device Address |
<serial_port>:<mbus_address> |
Settings |
[<baudrate>] |
Channel Address |
<dib>:<vib> |
Device Address
The serial port should be given that connects to the M-Bus converter. (e.g. /dev/ttyS0, /dev/ttyUSB0 on Linux). Shall be the primary M-Bus address of the meter (e.g. 1 for primary address 1).
Settings
The settings consist only of the serial port settings of the syntax <baudrate>. If left empty the default is used: "2400"
Channel Address
Shall be of the format <dib>:<vib> in a hexadecimal string format (e.g. 04:03 or 02:fd48)
5.3. M-Bus (wireless)
Wireless M-Bus is communication protocol to read out meters and sensors.
Configuration Synopsis |
|
ID |
wmbus |
Device Address |
<serial_port>:<secondary_address> |
Settings |
<transceiver> <mode> [<key>] |
Channel Address |
<dib>:<vib> |
Device Address
<serial_port> - The serial port used for communication. Examples are /dev/ttyS0 (Linux) or COM1 (Windows)
<secondary_address> - The secondary address consists of 8 bytes that should be specified in hexadecimal form. (e.g. e30456a6b72e3e4e)
Settings
<transceiver> - The transceiver being used. It can be amber or rc for modules from RadioCrafts.
<mode> - The wM-Bus mode can be S or T.
<key> - The key in hexadecimal form.
Channel Address
Shall be of the format <dib>:<vib> in a hexadecimal string format (e.g. 04:03 or 02:fd48)
5.4. IEC 61850
IEC 61850 is an international communication standard used mostly for substation automation and controlling distributed energy resources (DER). The IEC 61850 driver uses the client library from the OpenIEC61850 project.
Configuration Synopsis |
|
ID |
iec61850 |
Device Address |
<host>[:<port>] |
Settings |
[-a <authentication parameter>] [-lt <local t-selector>] [-rt <remote t-selector>] |
Channel Address |
<bda reference>:<fc> |
Channel Address
The channel address should be the IEC 61850 Object Reference and the Functional Constraint of the Basic Data Attribute that is to be addressed separated by a colon. Note that an IEC 61850 timestamp received will be converted to a LongValue that represents the milliseconds since 1970. Some information is lost during this conversion because the IEC 61850 timestamp is more exact.
Settings
The defaults for TSelLocal and TSelRemote are "00" and "01" respectively. You can also set either TSelector to the empty string (e.g. "-lt -rt"). This way they will be omitted in the connection request.
5.5. DLMS/COSEM
DLMS/COSEM is a international standardized protocol used mostly to communicate with smart meter devices. The DLMS/COSEM driver uses the client library developed by the jDLMS project. Currently, the DLMS/COSEM driver supports communication via HDLC and TCP/IP using Logical Name Referencing to retrieve values from the device.
Dependencies: rxtxcomm_api-2.1.7.jar (optional)
Configuration Synopsis |
|
ID |
dlms |
Device Address |
hdlc:<serial-port>[:<server-physical-port>]:<server-logical>:<client-logical> |
Settings |
[SendDisconnect=<disconnect>];[UseHandshake=<handshake>];[…] |
Channel Address |
<class-id>/<reference-id>/<attribute-id> |
Interface Address
The interface address consists of all elements the driver needs to uniquely identify and address a physical smart meter and format depends on the used protocol. Refer to the following table for the format of the interface address.
Protocol | Physical-Connection | Example |
---|---|---|
hdlc |
<serial-port>[:<server-physical-port>] |
hdlc:ttyUSB0 or hdlc:ttyUSB0:16 |
tcp |
<server-ip>[:<server-port>] |
tcp:16:192.168.200.25 or tcp:16:192.168.200.25:4059 |
Device Address
The device address contains all data necessary to connect to a logical device of the smart meter. Both the server-logical and client-logical address are each a 16-Bit unsigned number. The server-logical address is needed to identify a logical device inside a smart meter. In most cases, there are 2 logical devices inside a smart meter with the first being a management device to get common information and data about other logical devices in this smart meter while the second logical device is the smart meter itself holding the tariff and measurement data. The management device has the address 1, the address of the second device is manufacturer specific but can be read from the management device. If the physical device acts as a hub for other smart meter, the number of logical devices increases accordingly. The client-logical address is often used in conjunction with a password to identify the access level of the client. For the lowest access level (Public client) the client-logical address 16 with no password is reserved by the IEC 62056-46 and IEC 62056-47 norm.
Channel Address
A channel address references a single attribute of a COSEM Interface Object. To uniquely identify an attribute, the class-id, reference-id and attribute-id are needed, each separated by the slash character. The class-id and attribute-id are each a 16 bit unsigned number, while the reference-id needs to be the 6 byte OBIS code as it is defined by the DLMS UA. The reference-id can be written as hexadecimal number (e.g. 0101010800FF) or as a series of six decimal numbers separated by periods (1.1.1.8.0.255).
For a list of all valid reference-ids and the corresponding COSEM Interface Class, consult the list of standardized OBIS codes administered by the DLMS UA here
Settings
Settings are separated by a semi-colon. The available settings are determined by the used protocol, defined as first parameter of the device address. All possible settings with a short description and default values are listed in the following table.
Options | Protocol | Values | Default | Description |
---|---|---|---|---|
PW |
all |
string |
Authorization password to access the smart meter device |
|
SendDisconnect |
all |
true/false |
true |
Send a disconnect message at DLMS layer on disconnecting from device. Set this flag to false if the remote device is expecting the disconnect message at a lower layer (like HDLC) |
UseHandshake |
HDLC |
true/false |
true |
Use initial handshake to negotiate baud rate |
Baudrate |
HDLC |
integer |
Maximum supported baud rate (0 = no maximum). If UseHandshake = false, this value will be used to communicate with the device and has to be set |
|
ForceSingle |
all |
true/false |
false |
Forces every attribute to be requested individually. This option has to be enabled to support Kamstrup 382 smart meter devices |
5.6. KNX
KNX is a standardised protocol for intelligent buildings. The KNX driver uses KNXnet/IP to connect to the wired KNX BUS or a RC1180 UART (e. g. Calao USB-KNX-RF-C0X) to connect to RF. The driver supports group read and writes and is also able to listen to the BUS. The driver uses the calimero library.
Dependencies: rxtxcomm_api-2.1.7.jar
Configuration Synopsis for KNXnet/IP |
|
ID |
knx |
Device Address |
knxip://<host_ip>[:<port>] knxip://<device_ip>[:<port>] |
Settings |
[Address=<Individual KNX address (e. g. 2.6.52)>];[SerialNumber=<Serial number>] |
Channel Address |
<Group Adress>:<DPT_ID> |
Configuration Synopsis for RC1180 |
|
ID |
knx |
Device Address |
knxrc1180://<serialPort> |
Settings |
[Address=<Individual KNX address (e. g. 2.6.52)>];[SerialNumber=<Serial number>] |
Channel Address |
<Group Adress>:<DPT_ID>[:<AET>:<SNorDoA>] |
Device Address
For KNXnet/IP the device address consists of the host IP and the IP of the KNX tunnel or router. For RC1180 the device address is the serial port (e. g. knxrc1180://dev/ttyUSB0).
Channel Address
The channel address consist of the group address you want to monitor and the corresponding data point ID. A data point consists of a main number and a subtype. For example a boolean would be represented by the main number 1 and a switch by the subtype 001, the DPT_ID of a switch is 1.001. For a wireless connection there is also the possibility to change the serial number or domain address for each group write. scanForChannels() will return the specific channel address.
5.7. EHZ
OpenMUC driver for SML and IEC 62056-21
Dependencies: rxtxcomm_api-2.1.7.jar
Configuration Synopsis for EHZ |
|
ID |
ehz |
Device Address |
sml://<serialPort> or iec://<serialPort> |
Settings |
|
Channel Address |
<OBIScode> e.g. 10181ff (not 1-0:1.8.1*255) |
scanForDevices() and scanForChannels will return the specific configuration.
5.8. CANopen
OpenMUC driver to access generic CANopen devices. The driver is able to read and write the CANopen object dictionary as well as to listen for PDOs.
This driver uses the socketcan project to access the CAN network, therefore Linux is needed. But the jCANopen library can easily be expanded to access the CAN network with Windows.
Configuration Synopsis for CANopen |
|
ID |
canopen |
Device Address |
Name of the interface |
Settings |
[NMT];[SYNC=<time ms>] |
Channel Address |
SDO:<CAN ID>:<Object Index>:<Object Subindex>[:<Data Type>] |
Device Address
The device address consists of the name of the interface e.g. "can0"
Settings:
NMT: The driver controls the CAN network e.g. starts and stops nodes.
SYNC: The driver sends a sync package, may be necessary to receive PDOs
Channel Address
The channel address can either be a SDO or a PDO
SDO:<CAN ID>:<Object Index>:<Object Subindex>[:<Data Type>]
e.g. SDO:0x1:0x7130:1:INTEGER16
PDO:<PDO ID>:<Position>:<Length>[:<Data Type>]
e.g. PDO:0x181:0:16:INTEGER16
Data Type: <UNSIGNED8|UNSIGNED16|…|INTEGER8|…|REAL32|REAL64>
PDO ID: The COB ID of the PDO message
Position: PDOs with the same ID are sorted by the position and aligned by the length
Length: The length, in bit, of the specified data in this PDO
IDs and numbers are either decimal (42) or hex (0x2A)
5.9. SNMP
Simple Network Management Protocol (SNMP) is an Internet-standard protocol for monitoring and management of devices on IP networks.
Dependencies: snmp4j-2.2.5.jar
Configuration Synopsis |
|
ID |
snmp |
Device Address |
IP/snmpPort |
Settings |
settings string |
Channel Address |
SNMP OID address |
Device Address
IP address and available SNMP port of the target device should be provided as Device Address.
Example for Device Address:
192.168.1.1/161
Settings
All settings are stored in "SnmpDriverSettingVariableNames" enum.
Setting Parameters |
|
SNMPVersion |
"SNMPVersion" enum contains all available values |
USERNAME |
string |
SECURITYNAME |
string |
AUTHENTICATIONPASSPHRASE |
is the same COMMUNITY word in SNMP V2c |
PRIVACYPASSPHRASE |
string |
SNMPVersion
SNMPVersion is an enum variable containing valid SNMP versions. (V1, V2c, V3)
Example for valid settings string:
SNMPVersion=V2c:USERNAME=public:SECURITYNAME=public:AUTHENTICATIONPASSPHRASE=password
In order to read specific channel, corresponding SNMP OID shall be passed.
Example for SNMP OID:
1.3.6.1.2.1.1.1.0
For scanning SNMP enabled devices in the network, range of IP addresses shall be provided. This functionality is implemented only for SNMP V2c.
6. Developing a Driver
TBD
7. Data Loggers
7.1. SlotsDB
For configuration purposes, the id of SlotsDB is "slotsdb".
TBD
7.2. ASCII Logger
Use "asciilogger" as id to refer to the ASCII Logger in configurations.
TBD
8. Servers
Servers provide applications outside the OpenMUC Framework access to registered channels and/or the configuration of the Framework.
8.1. RESTful Web Service
The openmuc-server-restws bundle manages a RESTful web service to access all registered channels of the framework. The RESTful web service is accessed by the same port as the web interface mentioned in Chapter 2.
![]() |
The address to access the web service using the provided demo/framework folder is http://localhost:8888/rest/ |
8.1.1. Requirements
In order to start the RESTful web service, the following bundle must be provided:
-
Bundle that provides an org.osgi.service.http.HttpService service. In the demo framework, that service is provided by the org.apache.felix.http.jetty bundle.
This bundles is already provided by the demo framework. The RESTful web service will start automatically with the framework without additional settings.
8.1.2. Accessing channels
The latest record of a single channel can be accessed, by sending a GET request at the address: http://server-address/rest/channels/{id} where {id} is replaced with the actual channel ID. The result will be latest record object of the channel encoded in JSON with the following structure:
{
"timestamp" : time_val, /*milliseconds since Unix epoch*/
"flag" : flag_val, /*status flag of the record as string*/
"value" : value_val /*actual value. Omitted if "flag" != "valid"*/
}
You can access logged values of a channel by adding /history?from=fromTimestamp&until=untilTimestamp to the channel address, fromTimestamp and untilTimestamp are both milliseconds since Unix epoch (1970-01-01 00:00:00). The result is a collection of records encoded as JSON.
Additionaly, the records off all available channels can be read in one go, by omitting the ID from the address. The result is a collection of channel objects encoded in JSON using this structure:
[
{
"id" : channel1_id, /*ID of the channel as string*/
"record" : channel1_record /*current record. see Record JSON*/
},
{
"id" : channel2_id,
"record" : channel2_record
}
...
]
New records can be written to channels by sending a PUT request at the address that represents a channel. The data in the put request is a record encoded as specified in Record JSON above.
If HTTPS is used to access the REST server then HTTP basic authentication is required. The login credentials are the same as the one used to log into the web interface of the OpenMUC Framework.
9. Enabling HTTPS Connections
To enable secure and encrypted communication with the OpenMUC Framework using HTTPS, some steps that are illustrated in this chapter have to be made first. After these steps are performed, the WebUI as well as RESTful web service can be accessed using HTTPS.
9.1. Getting an SSL/TLS certificate
To establish an HTTPS connection, you need a certificate that confirms that you are who you claim to be. There are two possible ways for aquiring an SSL/TLS certificate.
The first possible way to get a certificate is by letting a certificate authority (CA) issue one to you. The exact course of action differs from CA to CA, and in most cases these certificates can have annual fees in the range of up to 1500$; in general these certificates are trusted by every major web browser and operating system without further configuration on client or server side. For are comparison of CAs, you can consult this table.
After you have aquired a certificate from a CA, you can add it with the following command to a java keystore:
keytool -importkeystore -srckeystore pfxfile.pxf -srcstoretype pkcs12 -destkeystore clientcert.jks -deststoretype JKS
The other method of aquiring a certificate is by creating a self signed one using the keytool
program shipped with the JRE. As there are no CAs involved in creating this certificate, there are no implied consts in creating and maintaining a self signed certificate. On the other hand, because everyone can create a certificate with your name, self signed certificates aren’t trusted by default. The user has to accept the certificate in his browser or you have to program your app in a way that it accepts your own certificate. Because of this, using self signed certificates is only recommended if the OpenMUC Framework is used in an internal team or a small user group.
To create a self signed certificate, use the following command:
keytool -keystore clientcert.jks -genkey -keyalg RSA -alias OpenMUC -validity 365
After all prompts have been filled out, the certificate is created in the file named after the -keystore
parameter (clientcert.jks in the example). Make sure that the question about your first and last name is answered with the fully qualified name of the server that runs the OpenMUC framework, otherwise your client will get a notification, that the certificate and server name don’t match.
![]() |
The Demo Framework provides a self signed certificate that can be used for demonstration purposes. The certificate is in the keystore named OpenMUC.jks in the framework folder. The password to access the keystore is https4OpenMUC. A password to access the certificate is not set. |
9.2. Configurating Jetty to use HTTPS
The Jetty HTTP-Server bundled with the Demo Framework supports HTTPS connections natively without the need to install additional bundles. To enable HTTPS connections, just fill out the following lines as stated in the table and add these to the config.properties file located inside the conf folder:
org.apache.felix.https.enable |
true |
org.apache.felix.https.keystore |
Location of the certificate from step 1 |
org.apache.felix.https.keystore.password |
Password to access keystore |
org.apache.felix.https.keystore.key.password |
Password to access certificate inside keystore (if any) |
org.osgi.service.http.port.secure |
Port to use for HTTPS |
To use the self signed certificate you would add the following lines to config.properties:
org.apache.felix.https.enable = true
org.apache.felix.https.keystore = OpenMUC.jks
org.apache.felix.https.keystore.password = https4OpenMUC
org.osgi.service.http.port.secure = 8800
If the configuration is correct, Jetty will enable the support for HTTPS connection the next time it is started.
10. OpenMUCs Channel Concept
OpenMUC works on the basis of channels. A channel basically represents a single data point inside a device which can be read and/or written via the according protocol driver. Some examples for a channel are the metered active power of a smart meter, the temperature of a temperature sensor, any value of digital or analog I/O module or the some manufacture data of the device. So a channel can represent any data which is accessible through applied protocol. The following picture illustrates the channel concept.
12. Authors
Developers:
-
Stefan Feuerhahn
-
Marco Mittelsdorf
-
Dirk Zimmermann
Former developers:
-
Michael Zillgith
-
Karsten Müller-Bier
-
Simon Fey
-
Frederic Robra