Calimero 1.x - EIBnet/IP Tunnelling (and more) for Java

(The content on this page is largely drawn from this presentation at the 2005 KNX Scientific Conference. Note that Calimero 2 is significantly different from Calimero 1 which is described here.)

Design

Calimero is a collection of Java APIs that together form a foundation for further EIB/KNX high level applications (including remote access and control). A client application is included, but intended for demonstration purposes only.

Calimero packages overview Eibclient is a EIBnet/IP client library that supports Tunnelling connections as well as search and description. The aim of this API‘s is to allow the establishment of EIBNet/IP connections with minimal effort. The entire EIBnet/IP message exchange including heart beating is hidden from the client programmer, who merely is faced with an API to send and receive cEMI messages. In addition, eibclient is able to parse cEMI messages to extract the relevant data as well as assemble them. The current implementation is limited to TP1 standard frames.

Eibxlator is a collection of encoders /decoders for Application layer protocol data units (APDUs) relevant for exchanging and interpreting group values. In this version only a subset of KNX DPT‘s are implemented, but the package was designed to make the addition of further ones easy.

Eibpoints offers the ability to maintain a list of the data points in the KNX/EIB system and their relevant data, including group address, friendly name, and DPT type. The data point list abstraction offers lookup facilities by name and address. The entire configuration can be exported and imported as an XML file or stream.

These APIs can be used largely independently.

Code Example

import java.net.*;
import tuwien.auto.*;
import tuwien.auto.eibxlator.*;
import tuwien.auto.eicl.*;
import tuwien.auto.eicl.util.*;
import tuwien.auto.eicl.struct.cemi.*;
import tuwien.auto.eicl.struct.eibnetip.util.*;


public class MainClass {

    public static void main(String[] args) {
		
        try {
            CEMI_Connection tunnel = new CEMI_Connection( 
                new InetSocketAddress("tunnelserver.somewhere.net",
                    EIBNETIP_Constants.EIBNETIP_PORT_NUMBER), 
                new TunnellingConnectionType());

            PointPDUXlator dimVal = PDUXlatorList.getPointPDUXlator(
                PDUXlatorList.TYPE_8BIT_UNSIGNED[0],
                PointPDUXlator_8BitUnsigned.DPT_SCALING[0]);

            dimVal.setServiceType(PointPDUXlator.A_GROUPVALUE_WRITE); 
            dimVal.setASDUfromString("75");

            CEMI_L_DATA message = new CEMI_L_DATA(
                CEMI_L_DATA.MC_L_DATAREQ,
                new EIB_Address(),
                new EIB_Address("0/0/1"),
                dimVal.getAPDUByteArray()); 

            tunnel.sendFrame(message, CEMI_Connection.WAIT_FOR_CONFIRM);
        }
        catch (EICLException ex) { }  // connection error

    }
}

This complete code example shows how easily a dimmer can be set to another value using the Calimero APIs. First, a new cEMI connection is instantiated, giving the name of the EIBnet/IP Tunnelling server and the default port number for EIBnet/IP. The constructor tries to establish a tunnelling connection with the server. If the operation succeeds and the Connect_Response frame has been received heartbeating is started and the constructor returns the cEMI connection object. If something goes wrong an Exception is thrown including an appropriate error message. The cEMI connection object not only allows to send and receive cEMI messages but also handles the heart beating and disconnection. For receiving, EventHandlers can be registered that are called on every incoming frame.

The next step is to construct a PDU translator. For this purpose the static method getPointPDUXlator of the PDUXlatorList class is called with the required major and minor type. If the requested DPT type is implemented an instance of the PointPDUXlator class, which is the base class for each PDUXlator implementation, is returned. If the major or minor type can not be found an Exception is thrown.

Then the service type is set, in our case a group value write request. The byte representation of the Layer 7 message can be retrieved using getAPDUByteArray(). Now we set the PDU translator value. Note that each PointPDUXlator class implements the abstract method setASDUfromString so that the values can be always set through this method, regardless of the specific type. If the parsing does not succeed an Exception is thrown.

All that is left to do is to set up a new cEMI L_Data request with the appropriate destination address and send it to the server. The source address can be left blank as the EIBNet/IP server will place its own address into it. We set the APDU bytes extracted from the translator as message body and send the frame using the tunnel instance.

In the example the send method WAIT_FOR_CONFIRM is used, in which the request sendFrame() blocks until the Tunnelling Ack and even the cEMI_L_Data.con message have been received. The other send mode, IMMEDIATE_SEND, returns immediately. The message status must in this case be checked explicitly using the getStatus() method.

Known Issues

Community patches

This section collects patches submitted by Calimero users which have not yet been reviewed and included in the codebase. Use at your own discretion and (as always) risk.

 

Get Calimero at SourceForge.net. Fast, secure and Free Open Source software downloads