GithubHelp home page GithubHelp logo

node-dsmr's Introduction

DSMR (Dutch Smart Meter Requirements) Parser

Build Coverage Status npm

The parser supports telegrams compliant to DSMR version 3.x, 4.x and 5.x, and eMUCs version 1.7.1 (since version 2).

Installation

npm install node-dsmr

Breaking changes

Version 2.0.0 introduced the following breaking changes:

  • Support for DSMR version 2.x has been dropped
  • The power section has been renamed to electricity, e.g. power.totalConsumed1 is now electricity.totalConsumed1
  • The properties instantaneousConsumedElectricityL1/L2/L3 and instantaneousProducedElectricityL1/L2/L3 are renamed to instantaneousConsumedPowerL1/L2/L3 and instantaneousProducedPowerL1/L2/L3

API

const SmartMeter = require('node-dsmr')

var options = {
    port: '/dev/ttyUSB0',
    baudrate: 9600,
    databits: 7,
    parity: 'even'
}

var smartmeter = new SmartMeter(options)

SmartMeter

Instantiate a new SmartMeter object by specifying the characteristics of the P1 port.

var smartMeter = new SmartMeter(options)

The arguments are:

  • port, serial port to which the P1 port is connected
  • baudrate, the rate at which the P1 port communicates, for DSMR 3.0 meters this is 9600 and for 4.x this is 115200.
  • databits, the number of bits used, for 3.0 meters this is 7 and for 4.x this is 8.
  • parity, the parity used, for 3.0 this is even and for 4.x this is none.
  • disableCrcChecking, when set to true the CRC check is disabled. The default is to check the CRC specified in the telegram with the calculated CRC, when they do not match, the telegram is not processed. When no CRC is specified as part of the telegram (e.g. for a DSMR 3.x message), the check is bypassed.

SmartMeter.connect

The connect method is used to connect and open the serial port.

smartMeter.connect()

Events

When an event happens, e.g. successful connection or a telegram has been received, the event will be emitted. By creating listeners for these events, the event can be processed in your code.

  • connected, a successful connection to the serial port has been made.

  • telegram, a new telegram has been received, the data of the event is the complete telegram as a JSON.

    Example:

    {
        electricity: {
            equipmentId: 'K8EG004046395507',
            totalConsumed1: 12345.678,
            totalConsumed2: 12345.678,
            totalProduced1: 12345.678,
            totalProduced2: 12345.678,
            activeTariff: 2,
            actualConsumed: 1.19,
            actualProduced: 0,
            switchPosition: 1
        },
        gas: {
            equipmentId: '2222ABCD12345678A',
            totalConsumed: 0,
            consumedLastPeriod: 0,
            reportedPeriod: 5,
            timestamp: 1234450800,
            valvePosition: 1
        },
        meterModel: 'ISk5\\2MT382-1000'
    }
  • update, a new telegram has been received with updated metrics, the data of the event contains the updated metrics as JSON. The electricity metrics presenting the actual consumption and/or production are continuously measured and for that reason always included in the update event, even when the actual value is the same as the previous measurement. The gas metrics presenting the total consumption is measured periodically as indicated with the included timestamp. When the timestamp indicates a new measurement has been performed the consumption since the last report is included even when 0. The total gas consumption is only reported when it has changed.

    Example:

    {
        "electricity": {
            "totalConsumed1": 123456.789,
            "activeTariff": 1,
            "actualConsumed": 1.193,
            "actualProduced": 0
        },
        "gas": {
            "reportedPeriod": 5,
            "consumedLastPeriod": 0
        }
    }

Reported metrics

The following metrics are reported when they are included in the telegram received from the P1 port:

Category Metric OBIS reference Description
meterModel
dsmrVersion 1-3:0.2.8
0-0:96.1.4
Version of the specification
timestamp 0-0:1.0.0 timestamp of the telegram
connectedMeters details of all connected meters (the electricity meter is always connected and not reported here)
electricity equipmentId 0-0:96.1.1
totalConsumed1 1-0:1.8.1 total consumption in tariff 1 in kWh
totalConsumed2 1-0:1.8.2 total consumption in tariff 2 in kWh
totalProduced1 1-0:2.8.1 total production in tariff 1 in kWh
totalProduced2 1-0:2.8.2 total production in tariff 2 in kWh
actualConsumed 1-0:1.7.0 actual consumption in kW
actualProduced 1-0:2.7.0 actual produced in kW
actualTariff 1-0:2.7.0 active tariff
failureLog 1-0:99.97.0 power failure event log (see below)
failures 0-0:96.7.21 number of power failures
failuresLong 0-0:96.7.9 number of long power failures
voltageSagsL1 1-0:32.32.0 Number of voltage dips on phase 1
voltageSagsL2 1-0:52.32.0 Number of voltage dips on phase 2
voltageSagsL3 1-0:72.32.0 Number of voltage dips on phase 3
voltageSwellsL1 1-0:32.36.0 Number of voltage peaks on phase 1
voltageSwellsL2 1-0:52.36.0 Number of voltage dips on phase 2
voltageSwellsL3 1-0:72.36.0 Number of voltage dips on phase 3
instantaneousCurrentL1 1-0:31.7.0 actual consumed current in Amperes on phase 1
instantaneousCurrentL2 1-0:51.7.0 actual consumed current in Amperes on phase 2
instantaneousCurrentL3 1-0:71.7.0 actual consumed current in Amperes on phase 3
instantaneousVoltageL1 1-0:32.7.0 actual voltage on phase 1
instantaneousVoltageL2 1-0:52.7.0 actual voltage on phase 2
instantaneousVoltageL3 1-0:72.7.0 actual voltage on phase 3
instantaneousConsumedPowerL1 1-0:21.7.0 actual consumed power in Watts on phase 1
instantaneousConsumedPowerL2 1-0:41.7.0 actual consumed power in Watts on phase 2
instantaneousConsumedPowerL3 1-0:61.7.0 actual consumed power in Watts on phase 3
instantaneousProducedPowerL1 1-0:22.7.0 actual produced power in Watts on phase 1
instantaneousProducedPowerL2 1-0:42.7.0 actual produced power in Watts on phase 2
instantaneousProducedPowerL3 1-0:62.7.0 actual produced power in Watts on phase 3
switchPosition 0-0:96.3.10 Switch position Electricity (in/out/enabled)
gas equipmentId 0-n:96.1.0
0-n:96.1.1
timestamp 0-n:24.2.1 timestamp of the last measurement
totalConsumed 0-n:24.2.1 measured total consumption
reportedPeriod 0-n:24.2.1 period in minutes over which the total consumption is reported
valvePosition 0-n:24.4.0
water equipmentId 0-n:96.1.0
0-n:96.1.1
timestamp 0-n:24.2.1 timestamp of the last measurement
totalConsumed 0-n:24.2.1 measured total consumption
reportedPeriod 0-n:24.2.1 period in minutes over which the total consumption is reported
valvePosition 0-n:24.4.0

Failures

DSMR version 4.x and 5.x might contain a failure event log which is reported as an array.

Example:

[
     {
         "timestampEnd": 1291818255,
         "duration": 240
     },
     {
         "timestampEnd": 1291817404,
         "duration": 301
     }
]

Parser

It is also possible to only use the parser without the connectivity logic:

const parser = require('node-dsmr/lib/parser');

const telegram = [
  '/ISk5\\2MT382-1000',
  '0-0:96.1.1(4B384547303034303436333935353037)',
  '1-0:1.8.1(12345.678*kWh)',
  '1-0:1.8.2(12345.678*kWh)',
  '1-0:2.8.1(12345.678*kWh)',
  '1-0:2.8.2(12345.678*kWh)',
  '0-0:96.14.0(0002)',
  '1-0:1.7.0(001.19*kW)',
  '1-0:2.7.0(000.00*kW)',
  '0-0:17.0.0(016*A)',
  '0-0:96.3.10(1)',
  '0-0:96.13.1(303132333435363738)',
  '0-0:96.13.0(303132333435363738393A3B3C3D3E3F303132333435363738393A3B3C3D3E3F 303132333435363738393A3B3C3D3E3F303132333435363738393A3B3C3D3E3F 303132333435363738393A3B3C3D3E3F)',
  '0-1:96.1.0(3232323241424344313233343536373839)',
  '0-1:24.1.0(03)',
  '0-1:24.3.0(090212160000)(00)(60)(1)(0-1:24.2.1)(m3)',
  '(00000.000)',
  '0-1:24.4.0(1)',
  '!'
]

console.log(parser(telegram))

Logging

Winston is used for logging. This means when you configure Winston in your code, the module will start to log accordingly. For instance, when you add the following to your code:

const logger = require('winston')

logger.remove(logger.transports.Console)
logger.add(new logger.transports.Console({
  format: logger.format.combine(
    logger.format.timestamp(),
    logger.format.colorize(),
    logger.format.printf(event => {
      return `${event.timestamp} ${event.level}: ${event.message}`
    })
  ),
  level: 'debug'
}))

The module will start logging to stdout with level debug.

node-dsmr's People

Contributors

dependabot[bot] avatar reneklootwijk avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

node-dsmr's Issues

Connected but not getting telegrams

When I manually open the serial connection I can see the telegrams:

# sudo cu -l /dev/ttyUSB0 -s 9600 -e -E q
Connected.
/ISk5\2MT382-1004

0-0:96.1.1(5A424556303035313832323533303133)
1-0:1.8.1(12500.539*kWh)
1-0:1.8.2(13054.067*kWh)
1-0:2.8.1(00000.000*kWh)
1-0:2.8.2(00000.002*kWh)
0-0:96.14.0(0002)
1-0:1.7.0(0000.50*kW)
1-0:2.7.0(0000.00*kW)
0-0:17.0.0(0999.00*kW)
0-0:96.3.10(1)
0-0:96.13.1()
0-0:96.13.0()
0-1:24.1.0(3)
0-1:96.1.0(4730303135353631313037313331333133)
0-1:24.3.0(200410180000)(00)(60)(1)(0-1:24.2.1)(m3)
(05780.901)
0-1:24.4.0(1)
!
/ISk5\2MT382-1004

The following also works:
sudo screen /dev/ttySUSB0 9600,cs7

When I run the following test script I only get "Connected" as the output:

const SmartMeter = require('node-dsmr')

var options = {
    port: '/dev/ttyUSB0',
    baudrate: 9600,
    bits: 7,
    parity: 'even'
}

var smartMeter = new SmartMeter(options)

smartMeter.connect()


smartMeter.on('connected', () => {
console.log('Connected')
})

smartMeter.on('telegram', telegram => {
console.log(telegram)
})

CRC check failing for every telegram

An older version of node-dsrm has been working fine for me for months. Today I updated to Node.js 14 (LTS) and updated all Node.js modules installed on my Raspberry Pi (I use this to get P1 data into my Homey via Homey p1 smartmeter DSMR reader).

Now I get a CRC check failure for every telegram:

{"message":"Telegram is not processed because of corruption (59ae/b9bc)","level":"error"}

As a workaround I added disableCrcChecking: true when initialising dsmr; P1 data are transferred fine then.

However, it would be nicer if the CRC check worked. What's wrong with my setup?

Timestamps of capacity runningMonth and history is fixed value

I found that timestamp of capacity.runningMonth and also in history 'start/end' items are fixed values rather then values taken from telegram.
I send you this telegram.

/FLU5\253769484_A

0-0:96.1.4(50217)

0-0:96.1.1(3153414733313030313835353436)

0-0:1.0.0(230206102154W)

1-0:1.8.1(002110.548*kWh)

1-0:1.8.2(003326.981*kWh)

1-0:2.8.1(008416.436*kWh)

1-0:2.8.2(003384.335*kWh)

0-0:96.14.0(0001)

1-0:1.4.0(00.000*kW)

1-0:1.6.0(230201170000W)(02.401*kW)

0-0:98.1.0(2)(1-0:1.6.0)(1-0:1.6.0)(230101000000W)(221202164500W)(02.772kW)(230201000000W)(230125170000W)(02.600kW)

1-0:1.7.0(00.000*kW)

1-0:2.7.0(00.902*kW)

1-0:21.7.0(00.108*kW)

1-0:41.7.0(00.000*kW)

1-0:61.7.0(00.000*kW)

1-0:22.7.0(00.000*kW)

1-0:42.7.0(00.376*kW)

1-0:62.7.0(00.634*kW)

1-0:32.7.0(233.1*V)

1-0:52.7.0(231.8*V)

1-0:72.7.0(235.2*V)

1-0:31.7.0(000.76*A)

1-0:51.7.0(001.78*A)

1-0:71.7.0(003.03*A)

0-0:96.3.10(1)

0-0:17.0.0(999.9*kW)

1-0:31.4.0(999*A)

0-0:96.13.0()

!3617

Consumed and Produced values for phases seem reversed?

First off, thanks for this package. It's a real lifesaver!

While using it, I however noticed the following:

Take the following values:

    instantaneousProducedElectricityL1: 0,
    instantaneousProducedElectricityL2: 0.476,
    instantaneousProducedElectricityL3: 0.571,
    instantaneousConsumedElectricityL1: 0.334,
    instantaneousConsumedElectricityL2: 0,
    instantaneousConsumedElectricityL3: 0

And looking at the actualConsumed and actualProduced values:

    actualConsumed: 1.047,
    actualProduced: 0.334,

It appears that the produced phase values add up to the actualConsumed value, and likewise the consumed values add up to the actualProduced value. This is consistently the case, without fail.

Perhaps this is intended (in which case could you explain why?), but I wanted to bring it to light in case it's a simple mistake. Thanks!

Cannot get any data from serial

Thanks for sharing this code. I've tried to work it out to build an simple script that can feed my home automation project.

If i use cu -l /dev/ttyUSB0 -s 115200 --parity=none -E q i can read successful the data.

After some hours i can get some logging working.

I only have an debug log: {"message":"Connection.connect: Entering","level":"debug"}.

Can you point to me where i should look?

const p1Meter = new smartMeter({
    port: '/dev/ttyUSB0',
    bps: 115200,
    bits: 8,
    parity: 'none',
})

p1Meter.on('connected', () => {
    console.log('connected')
})

p1Meter.on('update', line => {
    console.log(line)
})

p1Meter.on('disconnected', () => {
    console.log('disconnected')
})

p1Meter.connect()

Error finding 'label'

Most of the time dsmr-parser (2.04) is working well, but every now and then I get an error in debug window of node-red.
Undefined "label" ???

afbeelding

This is a normal P1 message:

`/Ene5\T211 ESMR 5.0

1-3:0.2.8(50)
0-0:1.0.0(230902152902S)
0-0:96.1.1(4530303632303030303130313639363232)
1-0:1.8.1(000352.869kWh)
1-0:1.8.2(000124.566
kWh)
1-0:2.8.1(000987.978kWh)
1-0:2.8.2(001760.544
kWh)
0-0:96.14.0(0001)
1-0:1.7.0(00.000kW)
1-0:2.7.0(01.319
kW)
0-0:96.7.21(00008)
0-0:96.7.9(00004)
1-0:99.97.0(1)(0-0:96.7.19)(220816003006S)(0000000380s)
1-0:32.32.0(00001)
1-0:52.32.0(00001)
1-0:72.32.0(00002)
1-0:32.36.0(00000)
1-0:52.36.0(00000)
1-0:72.36.0(00000)
0-0:96.13.0()
1-0:32.7.0(226.0
V)
1-0:52.7.0(226.0V)
1-0:72.7.0(227.0
V)
1-0:31.7.0(001A)
1-0:51.7.0(001
A)
1-0:71.7.0(003A)
1-0:21.7.0(00.000
kW)
1-0:41.7.0(00.000kW)
1-0:61.7.0(00.000
kW)
1-0:22.7.0(00.218kW)
1-0:42.7.0(00.322
kW)
1-0:62.7.0(00.778kW)
0-1:24.1.0(003)
0-1:96.1.0(4730303733303034313539343039353232)
0-1:24.2.1(230902152500S)(00013.636
m3)
!4774
`

issue with gas data

I have an issue with gas data, I can't figure out why.

Telegram looks like this:
afbeelding

As you can see, gas valve is open and gas volume is there.
But if I look at the parser data I see this:

afbeelding

As you can see, only the valve-position is there, but not "consumed" ????

strange characters

Hi,

When using node-dsr on a dutch electricity meter from 2011 I receive strange characters

{"message":"Unknown id: 0-0:96.�.�(�B����3�303035303�3�3�3�3�3�3�3���","level":"debug"}
{"message":"Unknown id: �-0:�.�.�(���35.�63���詍","level":"debug"}
{"message":"Unknown id: �-0:�.�.�(��9��.099���詍","level":"debug"}
{"message":"Unknown id: �-0:�.�.�(03�65.093���詍","level":"debug"}
{"message":"Unknown id: �-0:�.�.�(0�33�.�95���詍","level":"debug"}
{"message":"Unknown id: 0-0:96.��.0(000���","level":"debug"}
{"message":"Unknown id: �-0:�.�.0(0000.30��ש�","level":"debug"}
{"message":"Unknown id: �-0:�.�.0(0000.00��ש�","level":"debug"}
{"message":"Unknown id: 0-0:��.0.0(0999.00��ש�","level":"debug"}
{"message":"Unknown id: 0-0:96.3.�0(���","level":"debug"}
{"message":"Unknown id: 0-0:96.�3.�(��","level":"debug"}
{"message":"Unknown id: 0-0:96.�3.0(��","level":"debug"}
{"message":"Unknown id: 0-�:��.�.0(3��","level":"debug"}
{"message":"Unknown id: 0-�:96.�.0(3�3�3�303�353�3�3�303039303�3�3�3���","level":"debug"}
{"message":"Unknown id: 0-�:��.3.0(��������0000�(00�(60�(��(0-�:��.�.��(�3��","level":"debug"}
{"message":"Unknown id: 0-�:��.�.0(���","level":"debug"}
{"message":"SmartMeter: Telegram {"power":{},"gas":{}}","level":"debug"}
{"message":"p1 smartmeter update gas or power","level":"info"}

I'm using an old smartmeter, not sure what version (I think 2.x).

My settings are:

const usbPort = '/dev/ttyUSB0'
const bps = 9600
const bits = 7
const parity = 'none' (even is doing nothing)
const disableCrcChecking = 'true'

When I use a separate program called GTKTERM I've to use the following settings:

/dev/ttyUSB0, 9600, 7, E, 1

and then I receive normal data:

Schermafbeelding 2021-11-17 om 18 53 38

Can you help me out ?
Thanks in advance!

Abel

Incoherent results in consumed/produced vars

first of all, thanks for this nice module. Its being used by an app which I in turn use for Home automation using Homey. Using this app I noticed that my actual usage was shown as produced electricity instead of consumed electricity. Currently, I've got no electricity producing devices.

Delving into the app I concluded that the problem was your node-dsrm parser which labels the electricity incorrectly. As can be seen below, actualConsumed shows my current usage correctly, however, the usage per L* shows the usage in instantaneousProducedElectricityL* instead of instantaneousConsumedElectricityL*.

Any help fixing this is highly appreciated.

{ equipmentId: 'E00XXXXXXXXXX121',
  totalConsumed1: 849.545,
  totalConsumed2: 972.065,
  totalProduced1: 0,
  totalProduced2: 0,
  activeTariff: 2,
  actualConsumed: 0.444,
  actualProduced: 0,
  failures: 7,
  failuresLong: 2,
  failureLog: [],
  voltageSagsL1: 0,
  voltageSagsL2: 0,
  voltageSagsL3: 0,
  voltageSwellsL1: 1,
  voltageSwellsL2: 1,
  voltageSwellsL3: 1,
  instantaneousVoltageL1: 239.9,
  instantaneousVoltageL2: 239.1,
  instantaneousVoltageL3: 241.3,
  instantaneousCurrentL1: 1,
  instantaneousCurrentL2: 0,
  instantaneousCurrentL3: 1,
  instantaneousProducedElectricityL1: 0.234,
  instantaneousProducedElectricityL2: 0,
  instantaneousProducedElectricityL3: 0.209,
  instantaneousConsumedElectricityL1: 0,
  instantaneousConsumedElectricityL2: 0,
  instantaneousConsumedElectricityL3: 0 }

Capacity tarif and water data

Will there be an update for the Belgium meters to read out the capacity tariff data? Also the digital water meters are coming in 2023.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.