IClientConnectionFactory factory = ClientConnectionSettings.getFactory();
The jDLMS project is an open source Java library to communicate with smart meters using the protocol DLMS/COSEM, standardized as IEC 62056. DLMS/COSEM is an object based protocol specifically designed to communicate in a generic way with smart meters over multiple communication protocols. Currently, DLMS/COSEM supports communication over HDLC using a serial connection or over TCP/IP and UDP/IP.
This guide is no replacements for the IEC 62056 documents or the colored books administered by the DLMS User Association (DLMS UA). It merely scratches on the surface of this protocol, enough to get an idea how this library functions.
In DLMS/COSEM, a physical Smart Meter device can host several so called Logical Devices. These logical devices are addressed by a separate up to 2 Byte long number. As an example, a multi-energy meter can consist of one logical device for electricity metering on address 18 and another one for gas metering on address 67. No matter what type of smart meter it is, a DLMS/COSEM device must contain a special logical device called the management logical device at address 1. The content of this device may vary, but it must at least have a list of all logical devices inside the physical smart meter. You are always connecting to a single logical device with DLMS/COSEM.
Both server and client need an address to be uniquely identified. In case of the server, the address to identify a device consists of the physical address of the device (e.g. an IP address + port), as well as the address of the logical device (e.g. 1 for the management logical device).
On the other hand, the address of the client is highly dependant from the used communication protocol but always consists at least of one Byte to identify the nature client. In most cases, this Byte determines what objects you can read or write and what form of authentication is necessary to connect to the device. A special identifier is the number 16, which refers to the public client. This client address has the lowest rights and doesn’t need any authentication in most cases.
If HDLC is used as communication layer, the client address only consists of this single byte. Using TCP or UDP, the address additionaly consists of the IP and port of the client application.
As previously mentioned, DLMS/COSEM is an object based protocol. That means that the data of a device is grouped to objects. These objects are always an instance of a clearly defined interface class, similar to classes in object oriented programming languages. All available classes as well as their exact structure can be found in IEC 62056-62.
Objects can be addressed in two ways, depending on the connected smart meter. The recommended way is using the logical name of an object. A logical name, also known as OBIS code, is a 6 Byte long number that uniquely addresses a certain object over all smart meters. For example, the clock of a smart meter is always reachable under the address [0, 0, 1, 0, 0, 255]. The DLMS UA regulates what objects are under what addresses. A list of all possible logical names is published by the DLMS UA under the following site as an Excel sheet.
The other way to address an object is the so called short address. Short addresses is used for small devices and should only be used if the connected smart meter cannot communicate using logical names. The short address is a simple 2 Byte long number, instead of the 6 Byte long OBIS code mentioned above. The address space of short addresses is not regulated like the logical names, meaning that the same address can lead to different objects on different devices.
After the connection to a logical device has been established, communication occurs using the request-response model, meaning that the client requests a specific action and - after the request has been processed - the device sends the appropriate response back to the client.
Even though the data of the remote device are addressed in an object based fashion, data is accessed attribute based. So, in order to send a request, you have to send 3 parameters for uniquely identify the data and access it:
Class ID
Address of the object
Attribute ID
The class ID of an object can be extracted from the list mentioned earlier, while the exact attribute ID depends on the class ID and can be extracted the best way by consulting the document IEC 62056-62 or the Blue Book from the DLMS UA. As a rule of thumb, the first attribute of an object is its logical name, while the second attribute is the actual data. Further attributes usually include metadata like unit and scaling factor.
As an example that is used through the rest of this document, to access the current time on a smart meter you have to use the following parameters:
Class ID: 8 (Clock class)
Logical Name: [0, 0, 1, 0, 0, 255] (Current time)
Attribute ID: 2 (Data)
In the following chapter, we are writing a Java application to read the current time of a remote smart meter step by step.
The entry point of the jDLMS library is the interface IClientConnectionFactory. An object of this type creates objects of the type IClientConnection. These IClientConnection objects are your sole communication point to the device, all access is handled using methods of this object.
To create an object of IClientConnectionFactory, the easiest way is the static methodcreateFactory() of the ClientConnectionSettings class.
IClientConnectionFactory factory = ClientConnectionSettings.getFactory();
In order for factory to know what type of connection it has to create, you must give it an instance of one of ClientConnectionSettings subclasses. An instance of ClientConnectionSettingscontains all data needed to create a connection object. For this example, we assume that we are connecting to a smart meter with the IP address 192.168.200.25 and the port 4059 (the default port for DLMS/COSEM) using TCP. We will connect as public client (16) to the management logical device (1) and will use logical name (LN) referencing to access the data.
// Settings to connect to smart meter // - IP Destination: 192.168.200.25 (may vary) // - TCP Port: 4059 (DLMS standard) // - Address of logical device: 1 (Management Logical Device) // - Address of client: 16 (Public client) // - Referencing: Logical Name InetSocketAddress smartMeter = Inet4Address.getByName("192.168.200.25"), 4059); TcpClientConnectionSettings settings = new TcpClientConnectionSettings(smartMeter, 1, 16, ReferencingMethod.LN);
After settings has been created, factory can create an object of IClientConnection pointing to the remote device
IClientConnection connection = factory.createClientConnection(settings);
From this point on, only connection is needed to communicate with the smart meter.
So far, the connection object is created, but the connection itself is not established yet. A connection is generally established with one method call, but the number of parameter differ depending on the authentication the client needs. For our example, the public client needs no authentication (known in DLMS as lowest authentication). In this case, the only parameter we need to set is the amount of milliseconds we wait until the connecting attempt is aborted. We can safely assume that the connection cannot be established if it takes longer than 3 seconds, so our code to connect to the device looks like the following:
// Waiting 3s until connect attempt is canceled connection.connect(3000);
It’s as simple as that. Closing a connection is equally easy:
connection.disconnect();
On closing a connection, some smart meter devices are picky about what layer sends the disconnect message. Some devices expect the disconnect message on the DLMS layer, other expect a disconnect on the IP respectively HDLC layer. If nothing is said, jDLMS sends a disconnect message on the DLMS layer. That behavior can be altered by replacing the above line with disconnect(false). That way, the underlying communication layer sends the disconnect message.
To send a get request for reading the current time, we first have to create an address tuple that points to that attribute. For get requests, that tuple is an instance of the GetParameter class:
// Get parameter to read current time // - Interface class: 8 (Clock) // - Obis code: 0:0:1:0:0:255 (current time) // - Attribute ID: 2 (time) GetParameter getClock = new GetParameter(8, new ObisCode(0, 0, 1, 0, 0, 255), 2);
The constructor of the GetParameter class gets the class id and attribute id as integer and the logical name as an instance of the ObisCode class. The ObisCode class simply takes six bytes as input and preparates them to the right format for the library.
After getClock is created, all there is to do is tell the library to read that data from the smart meter:
// Read the current time from the remote device // Waiting 1s until aborting connection List<GetResult> results = connection.get(1000, getClock); GetResult getClockResult = results.get(0);
The getClockResult variable holds the data that the smart meter sent as response. It either holds the requested data, or an error code if something went wrong. A common way to handle the response would be the following snippet:
if (getClockResult.isSuccess()) { // Handle data in getClockResult.getResultData(); } else { // Handle according to error in getClockResult.getResultCode(); }
For setting a value or calling a method on the remote object, please refer to the javadoc of this library. Their behavior is similar to getting a value.
Below is the whole code that has been written in this example:
00001: public class DlmsExample { 00002: public static void main(String[] args) throws UnknownHostException, InterruptedException { 00003: // Settings to connect to smart meter 00004: // - IP Destination: 192.168.200.25 (may vary) 00005: // - TCP Port: 4059 (DLMS standard) 00006: // - WPort of smart meter: 1 (Management Logical Device) 00007: // - WPort of client: 16 (Public client) 00008: // - Referencing: Logical Name 00009: InetSocketAddress smartMeter = Inet4Address.getByName("192.168.200.25"), 4059); 00010: TcpClientConnectionSettings settings = new TcpClientConnectionSettings(smartMeter, 00011: 1, 16, ReferencingMethod.LN); 00012: 00013: IClientConnectionFactory factory = ClientConnectionSettings.getFactory(); 00014: IClientConnection connection = null; 00015: try { 00016: connection = factory.createClientConnection(settings); 00017: 00018: // Waiting 3s until connect attempt is canceled 00019: connection.connect(3000); 00020: System.out.println("\nConnected to smart meter\n"); 00021: 00022: // Get parameter to read current time 00023: // - Interface class: 8 (Clock) 00024: // - Obis code: 0:0:1:0:0:255 (current time) 00025: // - Attribute ID: 2 (time) 00026: GetParameter getClock = new GetParameter(8, new ObisCode(0, 0, 1, 0, 0, 00027: 255), 2); 00028: 00029: // Read the current time from the remote device 00030: // Waiting 1s until aborting connection 00031: List<GetResult> getResults = connection.get(1000, getClock); 00032: GetResult getClockResult = results.get(0); 00033: 00034: System.out.println("\nRead time from smart meter"); 00035: if (getClockResult.isSuccessful()) { 00036: // According to IEC 62056-62, the current time will be transmitted 00037: // as byte array 00038: System.out.println("Time: " + getClockString(getClockResult 00039: .getResultData().getByteArray())); 00040: } else { 00041: System.out.println("Error on reading time. ErrorCode: " 00042: + getClockResult.getResultCode()); 00043: } 00044: } catch (IOException e) { 00045: e.printStackTrace(); 00046: } finally { 00047: if (connection != null && connection.isConnected()) { 00048: connection.disconnect(); 00049: System.out.println("\nDisconnected from smart meter\n"); 00050: } 00051: } 00052: } 00053: 00054: /** 00055: * Helper method to extract the current date and time out of the byte array 00056: */ 00057: private static String getClockString(byte[] bytes) { 00058: int year = ((bytes[0] << 8) & 0xFF00) + (bytes[1] & 0xFF); 00059: int month = bytes[2]; 00060: int dayOfMonth = bytes[3]; 00061: String dayOfWeek = ""; 00062: switch (bytes[4]) { 00063: case 1: dayOfWeek = "Monday"; break; 00064: case 2: dayOfWeek = "Tuesday"; break; 00065: case 3: dayOfWeek = "Wednesday"; break; 00066: case 4: dayOfWeek = "Thursday"; break; 00067: case 5: dayOfWeek = "Friday"; break; 00068: case 6: dayOfWeek = "Saturday"; break; 00069: case 7: dayOfWeek = "Sunday"; break; 00070: } 00071: int hour = bytes[5]; 00072: int min = bytes[6]; 00073: int sec = bytes[7]; 00074: return dayOfWeek + " " + year + "/" + month + "/" + dayOfMonth + " " + hour 00075: + ":" + min + ":" + sec; 00076: } 00077: }
If you want to test the above example with another device, all you have to do is create anotherClientConnectionSettings object with the right parameters. For example, to read from a smart meter over HDLC, you would change the first two lines of code in the above main function with these:
HdlcAddress serverAddress = new HdlcAddress(1, 17, 2); HdlcClientConnectionSettings settings = new HdlcClientConnectionSettings("/dev/ttyUSB0", new HdlcAddress(16), serverAddress, ReferencingMethod.LN);
With the exemption of the disconnect function, you can leave the code as it is and it will connect to the new device over the serial line using HDLC. To do this, we create a HdlcAddress object in the first line. That address is 2 Bytes long and points to the logical device 1 at the physical device with the address 17. After that, we create an HdlcClientConnectionSettings instance that shall use /dev/ttyUSB0 to send and receive data, refer to itself as public client (one Byte HdlcAddress. Value: 16), connect to the address created earlier and use logical name addressing.
As you can see, after the IClientConnection object is created, there is no difference for the user of the library. Even if you have to change the object addressing method to short name (ReferencingMethod.SN), you still give the logical name of the object to the jDLMS and the library will handle the mapping internally.
Nearly not every problem can be solved using the public client, and sooner or later one needs added permissions to access data. If you want to write data to the smart meter you have to authorize as a client with more rights at the last. In order to do this, you have to modify the settings object before the IClientConnection object is created.
// Right after the settings object has been created settings.setAuthentication(Authentication.LOW);
On low authentication mode, you have to send a secret byte array as additional parameter when calling connection.connect(). For example, if the password would be "secret", encoded in US-ASCII, you would replace the connect line in above example with this line:
connection.connect(3000, "secret".getBytes("US-ASCII"))
If the password is wrong, an IOException is thrown and no connection is established.
Support for HIGH Authentication according to IEC 62056-62 has been implemented but is not tested up to this point, as we have no access to a smart meter supporting this authentication.
You can read multiple values with one request by chaining multiple GetParameter object into oneconnection.get() call. Additionaly, you can copy GetParameter objects with new attribute ids or logical names using changeAttributeId() and changeObisCode(). Note that GetParameter, like most other classes used to communicate with the library, is immutable. The object that is used to callchangeAttribute() will still refer to the same data as before the call.
To read the time zone and clock base additionally to the current time, you could add the following code:
// Get parameter to read timezone // - Attribute ID: 3 (timezone) // - Interface class & Obis code same as getClock request GetParameter getTimezone = getClock.changeAttributeId(3); // Get parameter to read clock base // - Attribute ID: 9 (clock base) // - Interface class & Obis code same as getClock request GetParameter getClockBase = getClock.changeAttributeId(9); // Read all three parameter with a single operation List<GetResult> getResults = connection.get(1000, getClock, getTimezone, getClockBase);
The jDLMS library will return a list of GetResults, the order of results is the same as the order of parameters inside the get(…) call. Beware that each operation can fail on its own, you have to check every GetResult item if the operation was successful. An Exception is only thrown if there was a problem with the communication itself.
文章浏览阅读4.2k次,点赞2次,收藏16次。1。为什么需要待机、休眠尽管电脑硬件运行速度越来越快,但操作系统的体积也在不断膨胀,使得电脑开、关机时,启动、关闭的程序越来越多,花费时间也越来越漫长。因此如何让电脑能够快速启动、一开机就进入Windows,就成为用户关心的问题。于是,随着硬件和软件的升级,操作系统开始引入了高级电源管理,其作用就是在电脑闲置时关闭部分设备,将电脑进入等待休息状态,这样当需要重新使用电脑时,能够直接从等待休息状态尽..._str待机
文章浏览阅读3.5k次,点赞2次,收藏7次。升级安装win7系统后,经常需要安装程序软件,安装程序过程中难免遇到一些错误问题,比如最近有些用户在Win7旗舰版系统中遇到一个问题,安装程序失败遇到错误代码0xc8000222,也不知道怎么处理。今天小编就来和大家介绍在Win7系统中安装程序时遇到错误0xc8000222的处理方法,有需要的用户一起来看下具体操作吧。Win7安装程序遇到错误代码0xc8000222的解决方法 解决方法: 1、点击“开始”->”所有程序”->”命令提示符”右键以管理员身份运行,然后输入:net stop W_0xc8000222
文章浏览阅读1.2k次。CentOS7挂载新数据盘的完整步骤前言刚刚买了一台新的VPS,新买的VPS的数据盘默认没有挂载到系统上,需要我们自己来挂载的。我们给服务器添加新的硬盘的时候都需要进行挂载操作,本文简要记录挂载操作过程。查看硬盘信息首先我们使用命令df -TH查看当前系统挂载的情况:我们看到并没有挂载新的数据盘,数据盘是200多G的。然后通过命令fdisk-l查看硬盘信息。可以看到有两块硬盘/dev/xvda和/..._已经装过centos7系统的硬盘如何挂载在新系统上
文章浏览阅读749次。使用rsa非对称加密 实现前后端加密通信 JSEncrypt和node-rsa_node rsa
文章浏览阅读2.1k次。 期现脱节下的悲剧——再看海南中商所F703咖啡事件 1995年12月21日,海南中商所宣布自F605合约始咖啡期货合约放大交割限量(交割总量由象征性的1吨扩大为1万吨),交割限量以外的头寸全部按进入交割月至最后交易日全部成交的加权平均价实行强制平仓。自F605始,中商所的咖啡品种演出了既不同于纽约咖啡行情又有别于历次中国期货交易风波的多幕闹剧。 回首咖啡F703事件 _海南咖啡事件认识和感悟
文章浏览阅读3.3k次,点赞2次,收藏7次。linux的内核参数,可以通过sysctl 命令进行配置和优化。实际参数很多,就不一一赘述了,大家可以在实际业务中适时的实践。_sysctl -p
文章浏览阅读1.4w次,点赞5次,收藏24次。一、背景 博主这边的小程序大部分都使用了web-view,众所周知,使用web-view最大的问题就是和小程序之间进行交互的问题。我这边主要是从web-view跳转回小程序的demo。二、通过web-view跳转到小程序页面1、微信官方文档微信web-view文档2、关于web-view页面的用法:Page({ data: { url: '你的we_webview跳转微信小程序页面
文章浏览阅读4.5k次,点赞5次,收藏31次。Eclipse配置Android开发环境在eclipse中配置Android开发环境在eclipse中配置Android开发环境在配置好环境的eclipse中安装Android SDK(Software Development Kit)和ADT插件。SDK的安装过程主要参考这篇博客。_eclipse配置安卓开发环境
文章浏览阅读541次,点赞6次,收藏9次。戴尔R720戴尔R730。
文章浏览阅读2.8k次,点赞3次,收藏19次。实验链接Xplico是一款开源的网络取证分析工具,其分析与呈现的能力非常强大。Xplico可以捕获Internet网络应用层流量,通过流量解析,解析出网络包中的各种应用数据,还原网络数据发送现场。通过本实验学习掌握Xplico使用方法,学会利用Xplico对网络流量进行分析取证。链接:http://www.hetianlab.com/expc.do?ce=10748f62-5706-403d-..._xplico
文章浏览阅读119次。Dockerfile 实战,搭建在 centos 上的 httpd。_doceker 镜像中增加驱动
文章浏览阅读2.7w次,点赞18次,收藏182次。临近期末,大一新生的各种考试和专业结课作业纷至沓来。web实训大作业、网页期末作业、web课程与设计、网页设计等,简直让人头大。你还在为网页设计老师的作业要求感到头大?网页作业无从下手?网页要求的总数量太多?没有合适的模板?等等一系列问题。你想要解决的问题,在这篇博文中基本都能满足你的需求, 废话不多说,直接看效果。网站布局方面:计划采用目前主流的、能兼容各大主流浏览器、显示效果稳定的浮动网页布局结构。网站程序方面:计划采用最新的网页编程语言HTML5+CSS3+JS程序语言完成网站的功能设计。并确_免费网页代码大全