The Noiasca Smartmeter Library

The Noiasca Smartmeter Library is a prototype to show the reading of Serial communication and extracting of data.

The Noiasca Smartmeter Library is based on the "Serial Input Basics - Example 4"  and implements the DSMR Protocol P1 like used on a Semax / Elster AM103.

DSMR Protocol P1 Basics

The DSMR Protocol P1 is an unecrypted, plaintext ASCII protocol. It transmits data line wise.

Each line begins with some identifiers followed with the value. Each line ends with a <CR><LF>.  The transmission ends with an ! and a CRC16 checksum.

Here is an incomplete example

0:1.0.0(211211212404W)
0-0:96.1.1(3230333830333738)
1-0:1.8.1(003112.307<em>kWh)
1-0:1.8.2(001106.447</em>kWh)
1-0:2.8.1(007040.886<em>kWh)
1-0:2.8.2(000052.335</em>kWh)
1-0:32.7.0(233.2"V)
1-0:52.7.0(235.4<em>V)
1-0:72.7.0(235.8</em>V)
1-0:31.7.0(007<em>A)
1-0:51.7.0(000</em>A)
1-0:71.7.0(000<em>A)
1-0:2.7.0(00.000</em>kW)
1-0:1.7.0()
!322D

Methods of Smartmeter P1 class

The library for the Smartmeter P1 protocol supports following member functions:

.getTimestamp() returns a point to the last received timestamp as delivered from the device in YYMMDDhhmmssW - 13 characters and a null limiter.
.getEquipmentIdentifier() returns a pointer to the equipment identifier - currently a maximum of 32 characters (including null limiter).
.getElectricityDeliveredToClient(byte tarif = 0) returns the client delivered electricity in kWh. Takes a tarif parameter. The protocol supports 16 tarifs (0..15), the P1 protocol is limited to two tarifs (either 0 or 1).
.getElectricityDeliveredByClient(byte tarif = 0)  returns the client delivered electricity in kWh. Takes a tarif parameter. The protocol supports 16 tarifs (0..15), the P1 protocol is limited to two tarifs (either 0 or 1).
.getInstantaneousVoltageL1() returns the voltage of L1 as float in Volt.
.getInstantaneousVoltageL2() returns the voltage of L2 as float in Volt.
.getInstantaneousVoltageL3() returns the voltage of L3 as float in Volt.
.getInstantaneousCurrentL1() returns the current of L1 as float in Ampere.
.getInstantaneousCurrentL2() returns the current of L2 as float in Ampere.
.getInstantaneousCurrentL3() returns the current of L3 as float in Ampere.
.getActualElectricityPowerReceived() returns the "electricity power received" as float in kW.
.getActualElectricityPowerDelivered() returns the "electricity power delivered" as float in kW.
.isDirty() returns a boolean. On the first received line of data the dirty flag will be set (true), the final CRC line will reset the flag to false.

Additionally you can define a callback function in your sketch. This callback function will be called, when the Transmission of new Data was completed.
.setOnNewData(callbackOnNewData) will inform the class to call "callbackOnNewData() whenever the data was updated completely. Obviously you must define the function callbackOnNewData() in your usersketch.

Please see the example 20_Smartmeter_Semax_Elster_AM103 for the usage of all smartmeter methods:

How to Test

When you do your testing, you can copy-paste the messages line wise to the serial monitor. If you have defined new data callback, don't forget to finalize your transmission with ! and a CRC16 - as only this will trigger your callback function:

!1234

Disclaimer

This library has prototype status. Don't expect a perfect working library. The CRC16 is currently not validated and each CRC16 will be accepted.

Links

(*) Disclosure: Some of the links above are affiliate links, meaning, at no additional cost to you I will earn a (little) comission if you click through and make a purchase. I only recommend products I own myself and I'm convinced they are useful for other makers.

History

First upload: 2021-12-12 | Version: 2024-03-22