Reading from a SDM120 meter using EmonHub

I think the problem may have been you used sudo in front of git. Don’t.

You need to post your emonhub.conf file please.

I suggest setting

node_format_enable: 0
nodevar_format_enable: 0
node_JSON_enable: 1
node_JSON_basetopic = emon/

Ensure the basetopic is emon/

I had to use sudo git to work around the ‘Permission denied’ error. If I want to avoid it, I probably have to change the rights (but I wouldn’t know to what):

/opt/openenergymonitor$ ls -al
totaal 16
drwxr-xr-x 4 root root 4096 mrt 31 16:22 .
drwxr-xr-x 3 root root 4096 mrt 31 16:19 ..
drwxr-xr-x 2 root root 4096 mrt 31 16:22 data
drwxr-xr-x 7 root root 4096 apr  1 19:12 emonhub

I’ve changed it to your suggested settings. My defaults were 0 where your settings were 1 (and vice versa). My /etc/emonhub/emonhub.conf: see emonhub.conf.txt (7.8 KB) . Thank you!

You never posted about that.

You created the folder using sudo - get out of that habit :slight_smile:

Set log level to DEBUG and restart the service.

[hub]
### loglevel must be one of DEBUG, INFO, WARNING, ERROR, and CRITICAL
loglevel = DEBUG

Do you see an entry in the emonhub.log like this (different data obviously).

2021-04-05 10:57:35,559 DEBUG    MQTT       Publishing: emon/emonpi {"power1": 125, "power2": 0, "power1pluspower2": 125, "vrms": 234.33, "t1": 0, "t2": 0, "t3": 0, "t4": 0, "t5": 0, "t6": 0, "pulsecount": 0, "time": 1617616655.2601027}

If not, what do you see in the log?

I “more or less” posted about the error: I wrote about .git/FETCH_HEAD: Toegang geweigerd which I translated to ‘access denied’. It’s only after export LC_ALL=C that I saw it had to be ‘Permission denied’. I’ll try to get rid of the sudo-habit :-). Once I have all of this working, I will reinstall everything from scratch.

I changed log level to DEBUG, restarted the service. More log: emonhub.log.txt (13.6 KB), but a relevant part seems to be:

2021-04-05 12:33:00,584 DEBUG    SDM120     [237.0, 0.0, 0.0, 0.0, 1.0, 50.0, 0.002, 0.0, 0.373]
2021-04-05 12:33:00,585 DEBUG    SDM120     1 NEW FRAME : 
2021-04-05 12:33:00,585 DEBUG    SDM120     1 Timestamp : 1617618780.057264
2021-04-05 12:33:00,586 DEBUG    SDM120     1 From Node : sdm120
2021-04-05 12:33:00,586 DEBUG    SDM120     1    Values : [237, 0, 0, 0, 1, 50, 0.002, 0, 0.373]
2021-04-05 12:33:00,586 DEBUG    SDM120     1 Sent to channel(start)' : ToEmonCMS
2021-04-05 12:33:00,587 DEBUG    SDM120     1 Sent to channel(end)' : ToEmonCMS
2021-04-05 12:33:00,659 INFO     MQTT       Connecting to MQTT Server
2021-04-05 12:33:00,661 INFO     MQTT       Could not connect...
2021-04-05 12:33:00,759 DEBUG    emoncmsorg Buffer size: 1
2021-04-05 12:33:10,557 DEBUG    SDM120     [237.6, 0.0, 0.0, 0.0, 1.0, 50.0, 0.002, 0.0, 0.373]
2021-04-05 12:33:10,558 DEBUG    SDM120     2 NEW FRAME : 
2021-04-05 12:33:10,558 DEBUG    SDM120     2 Timestamp : 1617618790.038961
2021-04-05 12:33:10,559 DEBUG    SDM120     2 From Node : sdm120
2021-04-05 12:33:10,559 DEBUG    SDM120     2    Values : [237.6, 0, 0, 0, 1, 50, 0.002, 0, 0.373]
2021-04-05 12:33:10,559 DEBUG    SDM120     2 Sent to channel(start)' : ToEmonCMS
2021-04-05 12:33:10,559 DEBUG    SDM120     2 Sent to channel(end)' : ToEmonCMS
2021-04-05 12:33:10,690 INFO     MQTT       Connecting to MQTT Server
2021-04-05 12:33:10,792 INFO     MQTT       connection status: Connection successful
2021-04-05 12:33:10,793 DEBUG    MQTT       CONACK => Return code: 0
2021-04-05 12:33:10,903 INFO     MQTT       on_subscribe
2021-04-05 12:33:20,605 DEBUG    SDM120     [237.2, 0.0, 0.0, 0.0, 1.0, 50.0, 0.002, 0.0, 0.373]
2021-04-05 12:33:20,606 DEBUG    SDM120     3 NEW FRAME : 
2021-04-05 12:33:20,606 DEBUG    SDM120     3 Timestamp : 1617618800.084261
2021-04-05 12:33:20,606 DEBUG    SDM120     3 From Node : sdm120
2021-04-05 12:33:20,607 DEBUG    SDM120     3    Values : [237.2, 0, 0, 0, 1, 50, 0.002, 0, 0.373]
2021-04-05 12:33:20,607 DEBUG    SDM120     3 Sent to channel(start)' : ToEmonCMS
2021-04-05 12:33:20,607 DEBUG    SDM120     3 Sent to channel(end)' : ToEmonCMS
2021-04-05 12:33:20,633 DEBUG    MQTT       Publishing: emon/sdm120 {"V": 237.2, "I": 0, "P": 0, "VA": 0, "PF": 1, "FR": 50, "EI": 0.002, "EE": 0, "RI": 0.373, "time": 1617618800.084261}
2021-04-05 12:33:30,564 DEBUG    SDM120     [236.8, 0.0, 0.0, 0.0, 1.0, 50.04, 0.002, 0.0, 0.373]
2021-04-05 12:33:30,565 DEBUG    SDM120     4 NEW FRAME :

So for the first frame there is a MQTT connection error, for the second frame the MQTT connection succeeds and from the third frame on I see a Publishing: emon/sdm120 {"V": 23...

If I understand correctly, the SDM120-interfacer uses the MQTT-interfacer? And does it also use the emoncmsorg-interfacer? In that case: the url setting is set to https://emoncms.org . There is a [nodes]-section as well, with numbers 5 to 26: do I have to mention anything about my SDM120? Or what could be the problem here?

Always is.

So you should see that data in the Inputs on your local emoncms (assuming it is pointing to the same MQTT Broker as emonhub).

What do you see in the emoncms logs?

IIRC you installed in an odd way - did you install the emoncms_mqtt service? This brings data in from the MQTT Broker to emoncms.

image

The ‘input’ interfacers are independent of the ‘output’ interfacers (input brings the data in and output sends it out [in simple terms]) so you bring the data in from 1 or more interfacers and send it out on one or more interfacers. For instance, I send the same data to several different MQTT Brokers.

[edit]
I think this may work but as you have an odd setup, no guarantees as the install scripts do other things.

In my admin panel, I only had emonhub, redis-server and mosquitto. So I took your link (thanks again), but needed to modify it a bit for my odd setup. The good news: it works (did I already thank you?)! I have my inputs! I quickly tried to make a feed, but that didn’t work yet. First I’ll read myself into it. I’ll beter use a new topic I guess if I have some troubles.

The steps to enable emoncms_mqtt (I tried some things and used this topic, so it might be they are not complete):

sudo ln -s /var/www/html/emoncms/scripts/services/emoncms_mqtt/emoncms_mqtt.service
/lib/systemd/system
sudo nano -w /etc/systemd/system/emoncms_mqtt.service (changed USER=pi and a path)
sudo apt-get install libmosquitto-dev
sudo pecl install Mosquitto-alpha
sudo phpenmod mosquitto
sudo systemctl daemon-reload
systemctl status emoncms_mqtt.service
1 Like

The graph module was missing, but I managed to install it. Now I have nice graphs. Thanks again @borpin!!

To experiment more with emoncms is the first on my 2DO list (might take a while). But to stay on topic: next is adding another SDM120 and a SDM630 in a modbus daisy chain. As far as I understand the EmonHubMinimalModbusInterfacer.py currently can’t handle this as the modbus adress is hard coded (self._rs485 = minimalmodbus.Instrument(device, 1)). Are there any plans to integrate that?

No immediate plans I’m afraid, your welcome to see if you can modify it to get this to work if you would like to give it a go? I did want to try something similar for the MBUS interfacer, but havent had a chance to look at that yet.

I’ll try to make it support modbus daisy chain reading. Might take a while :roll_eyes:. I’m just wondering if eg. these settings could work out as a base?

[[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
        nodename1 = heatpump
        modbus_addr1 = 1
        registers1 = 0,6,12,18,30,70,72,74,76
        names1 = V,I,P,VA,PF,FR,EI,EE,RI
        precision1 = 2,3,1,1,3,3,3,3,3
        nodename2 = pv
        modbus_addr2 = 2
        registers2 = 0,6,12,18,30,70,72,74,76
        names2 = V,I,P,VA,PF,FR,EI,EE,RI
        precision2 = 2,3,1,1,3,3,3,3,3

But then the runtimesettings would have 2 or more nodenames. And maybe that is impossible because of the internal workings of emonhub?

Another idea would be a [[SDM120_1]] and a [[SDM120_2]]. But then one must avoid that they read /dev/ttyUSB0 at the same time, because there is only one RS485 USB adapter at /dev/ttyUSB0. At least that is what I think the error is when I try to run my own script when the emonhub service in running in the background: minimalmodbus.NoResponseError: No communication with the instrument (no answer). Most of the time I don’t get that error, but I guess it happens when emonhub is reading as well (I see some null-values in emoncms as well).

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: https://github.com/openenergymonitor/emonhub/compare/minimalmodbus_address 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