Skip to content

Latest commit

 

History

History
311 lines (240 loc) · 15.4 KB

readme.adoc

File metadata and controls

311 lines (240 loc) · 15.4 KB

D0-SML to SMA Energy Meter converter

1. Introduction

This sketch reads SML telegrams from an infrared D0 interface of a smart meter and sends them as SMA energy-meter telegrams via UDP. Alternatively the telegrams can also be published via MQTT or polled via the REST interface of the integrated WebUI.

So far it has been tested with the following meters:

  • DWS74 from Deutsche Zählergesellschaft Oranienburg mbH

As hardware you need:

  • an ESP8266 (tested with NodeMCUv2 and WeMos D1 mini)

  • or a Raspberry Pi (tested with a Raspberry Pi 2)

  • a BPW40 phototransistor

  • and optionally a 1 KOhm resistor (only needed with a Raspberry Pi)

Caution

The source-code and the information in this document is provided as is. Use it at your own risk!

Thanks to Frank Carius for sharing his work. His sketch was the initial basis of this sketch.

2. Setup

2.1. ESP8266

2.1.1. Hardware

Attach the BPW40 transistorize to your ESP8266:

  • Short leg (collector, anode) to RxD

  • Long leg (emitter, cathode) to GND

Note

TxD is used to print debug-output.

2.1.2. Software

You need the Arduino IDE in order to compile and flash the sketch to the ESP8266.

Follow the instructions on the ESP8266 github project page or from ct magazine to setup your environment.

As additional dependencies you need:

Install these libraries via the Arduino IDE.

Flash layout

The pulse-counting feature stores the number of counted impulses in flash. To reserve flash, use the following layout:

4MB FS 1MB, OTA

Configuration

After compiling and flashing the software, the ESP8266 provides a WiFi access point with the name sml2emeter. To configure the software, connect to this access point with the password sml2emeter. If supported by your mobile device, you will automatically be redirected to the web-server of the ESP. If not, open a web-browser and enter the IP-address 192.168.4.1.

If everything works you should see an image like in [1].

configuration

To configure the ESP, press the [Configuration] button.

Note

If the device was already configured, you are asked for a username and password. The username is admin and the password the current AP password.

The configuration page is divided into four sections: WiFi configuration [2], meter configuration [3], MQTT configuration [4] and finally pulse-counting configuration [5].

WiFi configuration [2]
Thing name

Name of the device. This name is also used when in AP mode.

AP password

Password to connect to the device when in AP mode (mandatory). This password needs to be changed once the configuration of the device is done.

WiFi SSID

The name of the WiFi network (mandatory).

WiFi password

The password to connect to the WiFi network (mandatory).

Meter configuration [3]
Unicast address 1/2

Up to two unicast addresses may be specified as destination for energy-meter telegrams. If none is set, the default SMA energy meter multicast address (239.12.255.254) is used.

Port

Destination port for the energy-meter telegrams (default 9522). If any other port greater than 0 is set, raw SML packets will be send. If this value is set to 0, sending of energy-meter telegrams is turned off.

Serial number

The serial number which is used in the energy-meter telegrams.

MQTT configuration [4]
Broker address

Hostname of the MQTT broker.

Broker port

Port of the MQTT broker (default 1883). If this value is set to 0, publishing MQTT data is turned off.

If MQTT is enabled, the sketch publishes each telegram received from the energy-meter as JSON object on topic {thing name}/data.

Example using the mosquitto_sub command to print out received data
> mosquitto_sub -v -t "#"
sml2emeter/data {"PowerIn":297.32,"EnergyIn":4059843.70,"PowerOut":0.00,"EnergyOut":0.00}
Pulse counting configuration [5]

The pulse-counting may be used to count impulses from a gas-meter. For this, a reed-sensor must be attached to GPIO D1.

Debounce time

This value defines, how long (in ms) the signal of the reed-contact must be LOW until it is counted as an impulse. If this value is 0, pulse-counting is turned off.

Factor for m3 calculation

This value defines a factor to translate the impulses into a volume.

Note

If pulse-counting is enabled, then the MQTT messages contains two additional fields:

> mosquitto_sub -v -t "#"
sml2emeter/data {"PowerIn":297.32,"EnergyIn":4059843.70,"PowerOut":0.00,"EnergyOut":0.00,"Impulses":123,"m3":1.23}

It’s possibe to attach an LED to D5 to get a visual feed-back when the software has detected a LOW signal.

REST interface

Received energy-meter data can also be polled via HTTP: http://[hostname]/data

The returned JSON object is similar to the data published via MQTT:

{"PowerIn":90.59,"EnergyIn":4062453.10,"PowerOut":0.00,"EnergyOut":0.00,"Ok":468934,"ReadErrors":0,"ParseErrors":2}

2.2. Raspberry Pi

The software was originally developed for an ESP8266. Experimental support for the Raspberry Pi has been added and tested with a RaspberryPi 2. This version comes without a WebUI, MQTT and pulse-counting support.

2.2.1. Hardware

Check the documentation from Paul Görgen for settings up the Raspberry Pi and the hardware. In short:

  • Short leg (collector, anode) of the BPW40 to RxD

  • Long leg (emitter, cathode) of the BPW40 to GND

  • Put the resistor between RxD and 3,3V

Note

In Paul Görgens tutorial the BPW40 is used without a resistor. In my case this didn’t work and only fragments were received. Adding the resistor fixed that problem.

2.2.2. Software

You can compile the code directly on a Raspberry Pi. First run CMake to create a makefile, then use make to compile the application:

mkdir build
cd build
cmake ..
make

Please note that you have to configure your Raspberry Pi to use the serial interface for an own application (see documentation above) and to setup communication parameters to 9600 8N1.

Start the application by specifying the port, e.g.:

./sml2emeter /dev/ttyAMA0

3. Background information

3.1. Developing on a PC

For faster and more comfortable development it is possible to use Visual Studio or a GNU toolchain for compiling the sketch and running it on a PC. To create a solution, you need to run CMake first.

The python-script in the tools folder may be used to simulate a SML meter and to test everything without a real meter.

3.3. Example SML message

General structure of a SML message
SML {
	transactionId
	groupNo
	abortOnError
	messageBody
	crc16
	endOfMsg
}

Reference: p. 17

Example message
76                                                list                   SML message
   05 52 f1 58 00                                 string = R.X.          transactionId
   62 00                                          uint = 0               groupNo
   62 00                                          uint = 0               abortOnError(0 == continue, p.19)
   72                                             list                   messageBody (p.20)
      63 01 01                                    uint = 257               SML_PublicOpen.Res (p.22)
      76                                          list
         01                                       optional, not used         codepage
         01                                       optional, not used         clientId
         02 31                                    string = 1                 reqFileId
         0b 0a 01 44 5a 47 00 ff 00 ff 00         string = ..DZG.....        serverId
         72                                       list                       refTime
            62 01                                 uint                         type of time(1 == unsigned)
            64 1d a6 aa                           uint = 1943210
         62 02                                    uint = 2                   smlVersion
   63 d4 f4                                       uint = 54516           crc16
   00                                             endOfMessage
76                                                list                   SML message
   05 53 f1 58 00                                 string = S.X.          transactionId
   62 00                                          uint = 0               groupNo
   62 00                                          uint = 0               abortOnError(0 == continue, p.19)
   72                                             list                   messageBody (p.20)
      63 07 01                                    uint = 1793              SML_GetList.Res (p.36)
      77                                          list
         01                                       optional, not used         clientId
         0b 0a 01 44 5a 47 00 ff 00 ff 00         string = ..DZG.....        serviceId
         07 01 00 62 0a ff ff                     string = ......            listName
         72                                       list                       actSensorTime
            62 01                                 uint = 1
            64 1d a6 aa                           uint = 1943210
         75                                       list                       valList
            77                                    list
               07 01 00 60 01 00 ff               octed                      obis:Hardware version
               01                                 optional, not used
               72                                 list
                  62 01                           uint = 1
                  62 00                           uint = 0
               62 00                              uint = 0
               52 00                              int = 0
               04 44 5a 47                        string = DZG
               01                                 optional, not used
            77                                    list
               07 01 00 60 01 00 ff               octed                      obis:Device identification
               01                                 optional, not used
               72                                 list
                  62 01                           uint = 1
                  62 00                           uint = 0
               62 00                              uint = 0
               52 00                              int = 0
               0b 0a 01 44 5a 47 00 ff 00 ff 00   string = ..DZG.....
               01                                 optional, not used
            77                                    list
               07 01 00 01 08 00 ff               octed                      obis:Positive active energy (A+) total [Wh]
               64 1c 01 04                        uint = 1835268
               72                                 list
                  62 01                           uint = 1
                  62 00                           uint = 0
               62 1e                              uint = 30                  Unit
               52 ff                              int = 255                  Scale 10 ^ -1 = 0,1
               64 26 78 f4                        uint = 2521332             252133,2 Wh -> 252,1332 kWh -> 907679520 Ws
               01                                 optional, not used
            77                                    list
               07 01 00 02 08 00 ff               octed                      obis:Negative active energy (A+) total [Wh]
               01                                 optional, not used
               72                                 list
                  62 01                           uint = 1
                  62 00                           uint = 0
               62 1e                              uint = 30                  Unit
               52 ff                              int = 255                  Scale 10 ^ -1 = 0,1
               62 00                              uint = 0
               01                                 optional, not used
            77                                    list
               07 01 00 10 07 00 ff               octed                      obis:Sum active instantaneous power (A+ - A-) [W] (must be split to 1.4.0 and 2.4.0)
               01                                 optional, not used
               72                                 list
                  62 01                           uint = 1
                  62 00                           uint = 0
               62 1b                              uint = 27                  Unit
               52 fe                              int = 254                  Scale 10 ^ -2 = 0,01
               53 48 7a                           int = 18554                185,54 W
               01                                 optional, not used
         01                                       optional, not used	      listSignature
         01                                       optional, not used	      actGatewayTime
   63 9a 1e                                       uint = 39454           crc16
   00                                             endOfMessage
76                                                list                   SML message
   05 54 f1 58 00                                 string = T.X.          transactionId
   62 00                                          uint = 0               groupNo
   62 00                                          uint = 0               abortOnError(0 == continue, p.19)
   72                                             list                   messageBody (p.20)
      63 02 01                                    uint = 513               SML_PublicClose.Res (p.23)
      71                                          list
         01                                       optional, not used         signature
   63 60 79                                       uint = 24697           crc16
   00                                             endOfMessage
00                                                endOfMessage