Community
OpenEnergyMonitor

OpenEnergyMonitor Community

Reading from a SDM120 meter using EmonHub

Good question, that does get a bit tricky but your suggestion might work, these settings are all internal to the modbus interfacer and so it can choose to handle these in the way you suggest without requiring changes elsewhere in emonhub…

I wonder if this might work, might be easier to manage in terms on the implementation?:

[[SDM120]]
    Type = EmonHubMinimalModbusInterfacer
    [[[init_settings]]]
        device = /dev/ttyUSB0
        baud = 9600
        bytesize = 8
        parity   = PARITY_NONE
        stopbits = 1
        timeout  = 1
    [[[runtimesettings]]]
        pubchannels = ToEmonCMS,
        read_interval = 10
        [[[[devices]]]]
            [[[[[heatpump]]]]]
                modbus_addr = 1
                registers = 0,6,12,18,30,70,72,74,76
                names = V,I,P,VA,PF,FR,EI,EE,RI
                precision = 2,3,1,1,3,3,3,3,3
            [[[[[pv]]]]]
                modbus_addr = 2
                registers = 0,6,12,18,30,70,72,74,76
                names = V,I,P,VA,PF,FR,EI,EE,RI
                precision = 2,3,1,1,3,3,3,3,3

The [[SDM120]] wouldn’t be correct anymore with several kWh meters. Maybe [[ttyUSB0]] is better? Is that name within [[]] actually used somewhere or is it just an informative name? And maybe just like with other nodes it might be better to add units = V, A, W, ...?

I don’t know if the following, a bit different approach is better (like I said: newbe here :slight_smile: ):

[interfacers]
[[ttyUSB0]]
    Type = EmonHubMinimalModbusInterfacer
    [[[init_settings]]]
        device = /dev/ttyUSB0
        baud = 9600
        bytesize = 8
        parity   = PARITY_NONE
        stopbits = 1
        timeout  = 1
        nodeids = 27, 28, #must match the nodes in de [nodes] section
    [[[runtimesettings]]]
        pubchannels = ToEmonCMS,
        read_interval = 10        
        
[nodes]
## See config user guide: https://github.com/openenergymonitor/emonhub/blob/emon-pi/conf/emonhub.conf
[[27]]
    nodename = heatpump
    modbus_addres = 1
    [[[rx]]]
        registers = 0,6,12,18,30,70,72,74,76 # normally not present
        names = V,I,P,VA,PF,FR,EI,EE,RI
        # datacodes = h, h, h, h, h, h, h, h, h, h, L --> not necessary?
        # scales = 1,1,1,0.01,0.1,0.1,0.1,0.1,0.1,0.1,1
        precision = 2,3,1,1,3,3,3,3,3   # a bit like 'scales'?
        units = V, A, W, ...

[[28]]
    nodename = pv
    modbus_addres = 2
    [[[rx]]]
        registers = 0,6,12,18,30,70,72,74,76 # normally not present
        names = V,I,P,VA,PF,FR,EI,EE,RI
        precision = 2,3,1,1,3,3,3,3,3 # a bit like 'scales', but still not the same?
        units = V, A, W, ...       

I’m trying to test a python script with 2x SDM120 daisy chained on the same serial link. But I still have to add a try part and the SDM630 (see my question at stackoverflow). I’ll keep you updated.

@TrystanLea, any chance that you’ll find time for a different approach?

I also include three scripts I wrote:

  • sdm120.txt (2.1 KB) : just to test one SDM120.
  • sdm120_daisychain_sleep.txt (2.3 KB);: to test multiple daisy chained modbus meters. It uses time.sleep to avoid a minimalmodbus.NoResponseError.
  • sdm120_daisychain_alt.txt (2.6 KB) : to test multiple daisy chained modbus meters. This alternative uses try-except to avoid a minimalmodbus.NoResponseError.

I don’t understand much of the inner workings of emonhub nor EmonHubMinimalModbusInterfacer.py, but I hope you can use the last script to enable daisy chaining for EmonHubMinimalModbusInterfacer.py.

At the moment you could already help me if EmonHubMinimalModbusInterfacer.py could allow the modbus address to be set in emonhub.conf, eg:

        device = /dev/ttyUSB0
        address = 2
        ...

It would make my steps at topic Reading modbus kWh meters using EmonHub (SDM120 and SDM630) a tad shorter :slight_smile: .

I think (i.e. I’m not entirely sure) the cause of your timeouts is that you’re reading the same instrument rapidly in succession vice reading both instruments.

Here’s a code snippet from a script I use to read two WattsOn kWh meters via minimalmodbus.
I’ve never had an issue reading both meters, and I’ve never needed to use a delay between readings.

#!/usr/bin/python
import threading, datetime, time, logging, minimalmodbus, requests, os, os.path
from apscheduler.scheduler import Scheduler
from influxdb import InfluxDBClient as idbc

wattson1 = minimalmodbus.Instrument("/dev/USB0", 1)
wattson1.serial.baudrate = 9600
wattson2 = minimalmodbus.Instrument("/dev/USB0", 2)
wattson2.serial.baudrate = 9600

Note that you need a definition for each instrument you want to read.

You read the instruments like this:

VOLT = wattson1.read_float(792)        # voltage C-N
WHWH = wattson2.read_float(768)        # water htr Wh

Everything in this block except for the Baud rate is a minimalmodbus default.
The rest of the items don’t really need to be declared explicitly, although there’s
definitely no harm in doing so.

instrument.serial.baudrate = 9600         # Baud
instrument.serial.bytesize = 8
instrument.serial.parity   = minimalmodbus.serial.PARITY_NONE
instrument.serial.stopbits = 1
instrument.serial.timeout  = 1          # seconds
instrument.mode = minimalmodbus.MODE_RTU   # rtu or ascii mode

I have tried it before, but even with different definitions for each instrument, I couldn’t get it to work (see my initial post at stackoverflow). A user responds with “The Modbus specification established this value at 3.5 characters (the time it takes to send 3 and a half characters serially on the bus at the baud rate you are using). Unfortunately, some manufacturers do not stick to this rule. So some of those devices just take longer than 3.5 characters time to release control of the bus.

I know, but while I was testing I wanted to make sure every setting really was the correct one and that I didn’t overlook some setting :-). But thanks for the feedback!

Thanks @m2ts for this scripts and the great documentation of what you have done here Reading modbus kWh meters using EmonHub (SDM120 and SDM630). I will take a closer look at this and see what I can do. I have now merged the minimalmodbus branch into the master branch of emonhub which is one step forwards.

I haven’t tested this but hopefully the following should work for setting the address: Comparing master...minimalmodbus_address · openenergymonitor/emonhub · GitHub this is in a development branch so that it can be tested before merging.

I’ve just updated that to read from multiple addresses and tested reading from a single sdm120 that I have here, which still works fine. Let me know if it works for you @m2ts, should just need setting of addresses in the conf file like so:

[[SDM120]]
    Type = EmonHubMinimalModbusInterfacer
    [[[init_settings]]]
        device = /dev/ttyUSB0
        baud = 2400
    [[[runtimesettings]]]
        pubchannels = ToEmonCMS,
        read_interval = 10
        nodename = sdm120
        # prefix = sdm_
        addresses = 1,2,
        registers = 0,6,12,18,30,70,72,74,76
        names = V,I,P,VA,PF,FR,EI,EE,RI
        precision = 2,3,1,1,3,3,3,3,3

@TrystanLea, if I understand correctly this new code allows me to set the modbus address by editing emonhub.conf instead of EmonHubMinimalModbusInterfacer.py. But it doesn’t allow me to use daisy chaining yet. Correct?

I’m a bit confused about the addresses = 1,2,, shouldn’t it be address = 1 or address = 2 or …?

I’m just at my baby steps in using git, so I’m not sure how I can use the new code. The following didn’t seem to work.

cd /opt/openenergymonitor/emonhub
git fetch --all
git checkout minimalmodbus_address
git pull
sudo service emonhub restart

I got an error:

 error: Your local changes to the following files would be overwritten by checkout:
        src/interfacers/EmonHubMinimalModbusInterfacer.py
Please commit your changes or stash them before you switch branches.
Aborting

This means you have edited that file, correct?

I am guessing you can specify several addresses at once. Note the trailing comma is important.

daisy chaining should hopefully work… I copied the implementation that you put together in your code

Yes, indeed. I don’t know how I “override” that with a git command, but I renamed EmonHubMinimalModbusInterfacer.py to EmonHubMinimalModbusInterfacer.py.old and did the git-command again. This workaround seems to work as I now see the new code in EmonHubMinimalModbusInterfacer.py.

@TrystanLea, thanks! I have tried the new code, but at emoncms > Inputs, I only see the values (eg. P 5.7 W) of address 2.

What I don’t understand is that I can have a setting of multiple adresses (eg. addresses = 1,2,), but only one nodename. I would expect to also have two possible nodenames (eg. heatpump and solar). I would also expect to be able to have other registers for address 2 then 1 (eg. the SDM630 has some extra registers that the SDM120 doesn’t have). Or am I missing something? My config says:

[[SDM120]]
    Type = EmonHubMinimalModbusInterfacer
    [[[init_settings]]]
        device = /dev/ttyUSB_household
        #modbus_addres = 1
        baud = 9600
    [[[runtimesettings]]]
        pubchannels = ToEmonCMS,
        read_interval = 10
        nodename = heatpump
        # prefix = sdm_
        addresses = 1,2,
        registers = 0,6,12,18,30,70,72,74,76
        names = V,I,P,VA,PF,FR,EI,EE,RI
        precision = 2,3,1,1,3,3,3,3,3

IIRC if you do a git status it will give you the command. You need to checckout the original file from the upstream repository.

A little late to the party with this, but to avoid any confusion (for future readers of this thread)
M-Bus refers to Meter Bus.

Ref: https://m-bus.com/
M-Bus (Meter-Bus) is a European standard (EN 13757-2 physical and link layer, EN 13757-3 application layer) for the remote reading of water meter, gas or electricity meters. M-Bus is also usable for other types of consumption meters.

Not the same as, and incompatible with, Modbus.

[quote=“m2ts, post:118, topic:16475”]

@TrystanLea, any chance to have a look at the code. I still think that daisy chaining (namely reading the two SDM120s and one SDM630 on one serial line) isn’t possible with that code. A config-file like your post at 13 April or mine just after your post seems more logical to me. But again: I am a total newbie.

At the moment my SDM630 is already mounted in the fuse board. The two SDM120 aren’t, as I can experiment with them more easily. But I hope to be able to mount them soon :wink: .

Will hopefully get a chance to look at this soon, I will wire up a couple of modbus meters and see what I get. Im working on the similar requirement for multiple devices on a bus for the MBUS interfacer so will hopefully be able to apply what I learn from that to the modbus interfacer.

1 Like

@TrystanLea, hopefully you already had the chance to look at the modbus daisy chain readings… :slight_smile: ?

1 Like

Hello @m2ts I got a bit stuck with getting multiple MBUS devices to work on a single emonhub interfacer a couple of weeks back and ended up getting it working for the test I needed to do in a separate script. It’s on my list to revisit though and work out what the best solution is.

2 Likes

Late joiner to the party here - exciting progress. Having been looking for a robust approach to sub meter multiple high load circuits on OEM, v. much appreciate the efforts . We’ve just had to plunge into a full house rewire so have spec’d x5 sdm120’s as part of it. Hoping I can contribute to some testing re: modbus daisychaining in the near future.

1 Like

Hello @thedawnbefore great to hear.

Perhaps a relevant note, not sure, but having got the SDM120 to work here using MBUS rather than modbus, I’m going to use the MBUS versions going forward for my own heat pump monitoring related development. I can then use the same MBUS reader to do both the electricity and heat meters on the heat pump. If you need to do any heat metering using MBUS it might be worth considering speccing MBUS SDM120 meters instead…