Reading from a SDM120 meter using EmonHub

I will get on this now and make the changes to the code. Should have an updated version to test shortly.

@TrystanLea I have just submitted a PR

Please test it first if you use it as I was unable to test.

1 Like

Thanks @pb66

Thanks again @pb66, tested here, with a minor modification to the connection

self._sdm = sdm_modbus.SDM120(device=device, baud=int(baud))

it worked fine.

I will have a look at improving the options to name the parameters.

1 Like

I’ve added a prefix option which makes the sdm_ part optional.

[[SDM120]]
    Type = EmonHubSDM120Interfacer
    [[[init_settings]]]
        device = /dev/ttyUSB0
        baud = 2400
    [[[runtimesettings]]]
        pubchannels = ToEmonCMS,
        read_interval = 10
        nodename = SDM120
        # prefix = sdm_

In the code there is an array that defines the SDM120 key’s to read, short names and number of decimal points to round the value too:

    read_keys = {
        'voltage':('V',2),
        'power_active':('P',2),
        'power_factor':('PF',4),
        'frequency':('FR',4),
        'import_energy_active':('E',3),
        'current':('I',3)
    }

The parameters are then read if present in the data returned from the SDM120:

for i in read_keys:
    if i in r:
        c.names.append(self._settings['prefix']+read_keys[i][0])
        c.realdata.append(round(r[i],read_keys[i][1]))

The prefix is blank by default so inputs will appear under nodename SDM120, input names: V,P,PF etc.

My own use case is posting the SDM120 data alongside MBUS data under a single nodename called heatpumpmonitor and so the prefix is useful so that I can then set the inputs to be: heatpumpmonitor:sdm_V etc…

@srt these recent updates are still in the emonhub master branch for now. With a bit more testing I will merge them into stable and do a release. For now would you mind switching to this branch to test the new changes?

The steps are (via SSH):

cd /opt/openenergymonitor/emonhub
git checkout master
git pull

As @srt has modified some of the files, he will need to get rid of the changes by checking out that file first else Git will complain.

1 Like

One thing, I think it is bad form to drop experimental stuff into master - it should really go into a dev branch first IMHO, merged to master for final testing and then released as stable.

You have told me many times @borpin :slight_smile: I think there are too many steps, perhaps we should just have stable and development for the main branches… I do leave features in a specific feature branch when they are really experimental but try and bring them into master at least when they dont break anything else, even if the feature itself in this case the SDM120 reader is a very early version of the feature. I just find things go stale very quickly if left in feature branches for wider testing. I know I’m not going to get agreement on this.

Edit: I think @srt is the first person to use this in 2 months? or at least post an issue…

Why have you opted for hardcoded names albeit with a prefix rather than using the existing practice of using [nodes] definitions? “Voltage” is obviously more user friendly than “sdm_v” or just “v” especially as there is no way to change the names in emoncms if you want data via mqtt?

There is no reason you couldn’t have a default array of names eg sdm_v, sdm_p, etc and let users define their own array. Likewise for precision levels.

Although the oem emonhub follows the emonhub-wide [nodes] definitions I am veering towards interfacer level node definitions so rather than a [nodes] definition you could easily have names = voltage,power_active etc and precision = 2,2,4 etc in the interfacer [[runtimesettings]].

However, I personally would prefer to see users able to define any number of the available values in any order so they can create thier own node formats eg

   values = power_active, voltage
   names = Power, MainsVoltage
   precision = 2, 1

would give a node of 2 values, “Power” first to 0.01 units (I assume Watts?) and MainsVoltage to 0.1 volts. This might not have much effect on “status” type MQTT but when frames of data are posted via http (and hopefully MQTT too) you can select the order the inputs are read and processed, very important when using more than one input in a calculation during processing.

@pb66 true that could work fine, so the values setting would define the SDM120 parameter order to map to names and precision… is values the best name for this?

Whilst I don’t disaggree with what you say, the naming of the branches is what causes the confusion, ordinarily development is done in another branch eg “dev” and merged to “master” after final testing, only after a release has seen the test of time could it be called “stable” so really oem stable = master and oem master = dev since master is usually where the releases come from not from “stable” as is the case with oem.

1 Like

Ha Ha!

Yes naming is crucial, eg above eg rfm12pi (with rfm69 module) or emoncms id/name name/desc etc, not our strongest point, ay?

I’m not fixed on “values” it possibly isn’t right but it needs to be generic so that all interfacers can reuse without issue (for example using “interval” rather than “read_interval”), I was just floating the concept as I really don’t like hardcoded elements so IF changes were being made I hoped this would approach could be considered.

I first used this approach for the wunderground interfacer even before emonhub experimental branch.

[edit - just looked to see what I used back then]

Currently available datafields are “temp_c”, “feelslike_c”, “dewpoint_c”, “heat_index_c”, “windchill_c”, “wind_mph”, “wind_gust_mph”, “visibility_mi”, “precip_1hr_metric”, “precip_today_metric”, “UV”, “wind_degrees”, “pressure_mb”, “pressure_in”, “pressure_trend”, “relative_humidity”, “temp_f”, “feelslike_f”, “dewpoint_f”, “heat_index_f”, “windchill_f”, “wind_kph”, “wind_gust_kph”, “visibility_km”, “precip_1hr_in”, “precip_today_in”

Which any number can be strung together as csv, in any order to create a frame be passed to emoncms eg

datafields = relative_humidity, feelslike_c, pressure_mb

I think datafields works well, it’s generic and clear.

1 Like

Agreed and that is how I think it should be.

The risk is, merging directly to master, if someone is running master and using SDM120 and decides to do an update while all this is going on, they could easily break their system and wonder why!

Before doing anything, I take a branch off master and update that branch. You can then easily merge to master once it all works. Of course I cannot merge directly anyway :laughing:.

they should be aware they are using the oem equivalent of a staging dev branch.

The only issue (aside from the names) is that (IMO) the repo’s should use/display the stable branch by default and only hotfixes PR’d to that repo, features and rewrites go from a feature branch to master (aka dev).

1 Like

Yes I agree that would help ensure most people use the stable branch, the current arrangement does encourage the use of master for those installing manually

1 Like

OK, so I:
a) flipped the A/B terminals on the RS485/USB converter (I can see me doing this again…)
b)applied your git pull
c)restarted emonhub

emonhub runs, but there doesn’t seem to be any SDM data.

disclaimer: I have played a bit with RPi and python in the past, but it’s few and far between, so while I can ssh and execute commands, I really have no idea what I’m doing. And a little knowledge is a dangerous thing - so best treat me like an idiot. Meanwhile, here’s a chunk of log:

2021-01-21 16:13:20,583 INFO     MainThread Exiting hub...
2021-01-21 16:13:32,335 INFO     MainThread Exit completed
2021-01-21 16:13:34,897 INFO     MainThread EmonHub emonHub (emon-pi variant) v2.1.5
2021-01-21 16:13:34,898 INFO     MainThread Opening hub...
2021-01-21 16:13:34,899 INFO     MainThread Logging level set to DEBUG
2021-01-21 16:13:34,900 INFO     MainThread Creating EmonHubJeeInterfacer 'RFM2Pi'
2021-01-21 16:13:34,902 DEBUG    MainThread Opening serial port: /dev/ttyAMA0 @ 38400 bits/s
2021-01-21 16:13:36,910 INFO     MainThread RFM2Pi device firmware version & configuration: not available
2021-01-21 16:13:36,911 INFO     MainThread Setting RFM2Pi baseid: 5 (5i)
2021-01-21 16:13:37,913 INFO     MainThread Setting RFM2Pi frequency: 433 (4b)
2021-01-21 16:13:38,916 INFO     MainThread Setting RFM2Pi group: 210 (210g)
2021-01-21 16:13:39,918 INFO     MainThread Setting RFM2Pi quiet: 1 (1q)
2021-01-21 16:13:40,920 INFO     MainThread Setting RFM2Pi calibration: 230V (1p)
2021-01-21 16:13:41,923 DEBUG    MainThread Setting RFM2Pi pubchannels: ['ToEmonCMS']
2021-01-21 16:13:41,924 DEBUG    MainThread Setting RFM2Pi subchannels: ['ToRFM12']
2021-01-21 16:13:41,927 INFO     MainThread Creating EmonHubMqttInterfacer 'MQTT'
2021-01-21 16:13:41,932 DEBUG    RFM2Pi     device settings updated: E i5 g210 @ 433 MHz q1 USA 0
2021-01-21 16:13:41,933 DEBUG    MainThread Setting MQTT pubchannels: ['ToRFM12']
2021-01-21 16:13:41,935 DEBUG    MainThread Setting MQTT subchannels: ['ToEmonCMS']
2021-01-21 16:13:41,936 INFO     MainThread Setting MQTT node_format_enable: 1
2021-01-21 16:13:41,937 INFO     MainThread Setting MQTT nodevar_format_enable: 1
2021-01-21 16:13:41,938 INFO     MainThread Setting MQTT nodevar_format_basetopic: emon/
2021-01-21 16:13:41,939 INFO     MainThread Creating EmonHubEmoncmsHTTPInterfacer 'emoncmsorg'
2021-01-21 16:13:41,941 DEBUG    MainThread Setting emoncmsorg pubchannels: ['ToRFM12']
2021-01-21 16:13:41,942 DEBUG    MainThread Setting emoncmsorg subchannels: ['ToEmonCMS']
2021-01-21 16:13:41,943 WARNING  MainThread Setting emoncmsorg apikey: obscured
2021-01-21 16:13:41,943 INFO     MainThread Setting emoncmsorg url: https://emoncms.org
2021-01-21 16:13:41,944 INFO     MainThread Setting emoncmsorg senddata: 1
2021-01-21 16:13:41,944 INFO     MainThread Setting emoncmsorg sendstatus: 1
2021-01-21 16:13:41,946 INFO     MainThread Creating EmonHubSDM120Interfacer 'SDM120'
2021-01-21 16:13:41,958 INFO     MainThread Connecting to SDM120 device=/dev/ttyUSB0 baud=2400
2021-01-21 16:13:41,961 INFO     MainThread Setting SDM120 read_interval: 10
2021-01-21 16:13:41,962 INFO     MainThread Setting SDM120 nodename: SDM120
2021-01-21 16:13:41,962 INFO     MainThread Setting SDM120 prefix: 
2021-01-21 16:13:41,963 DEBUG    MainThread Setting SDM120 pubchannels: ['ToEmonCMS']
2021-01-21 16:13:42,037 DEBUG    RFM2Pi     device settings updated: E i5 g210 @ 433 MHz q1 USA 0
2021-01-21 16:13:42,141 DEBUG    RFM2Pi     device settings updated: E i5 g210 @ 433 MHz q1 USA 0
2021-01-21 16:13:42,249 DEBUG    RFM2Pi     1 NEW FRAME : OK 5 238 252 232 255 214 252 2 93 0 0 0 0 0 0 0 0 0 0 0 0 249 224 0 0 (-0)
2021-01-21 16:13:42,252 DEBUG    RFM2Pi     1 Timestamp : 1611245622.249539
2021-01-21 16:13:42,253 DEBUG    RFM2Pi     1 From Node : 5
2021-01-21 16:13:42,253 DEBUG    RFM2Pi     1    Values : [-786, -24, -810, 238.1, 0, 0, 0, 0, 0, 0, 57593]
2021-01-21 16:13:42,254 DEBUG    RFM2Pi     1 Sent to channel(start)' : ToEmonCMS
2021-01-21 16:13:42,254 DEBUG    RFM2Pi     1 Sent to channel(end)' : ToEmonCMS
2021-01-21 16:13:42,358 DEBUG    RFM2Pi     device settings updated: E i5 g210 @ 433 MHz q1 USA 0
2021-01-21 16:13:42,441 INFO     MQTT       Connecting to MQTT Server
2021-01-21 16:13:42,462 DEBUG    RFM2Pi     device settings updated: E i5 g210 @ 433 MHz q1 USA 0
2021-01-21 16:13:42,545 INFO     MQTT       connection status: Connection successful
2021-01-21 16:13:42,546 DEBUG    MQTT       CONACK => Return code: 0
2021-01-21 16:13:42,557 DEBUG    emoncmsorg Buffer size: 1
2021-01-21 16:13:42,648 INFO     MQTT       on_subscribe
2021-01-21 16:13:44,688 DEBUG    RFM2Pi     2 NEW FRAME : OK 5 234 252 233 255 211 252 36 93 0 0 0 0 0 0 0 0 0 0 0 0 252 224 0 0 (-0)
2021-01-21 16:13:44,690 DEBUG    RFM2Pi     2 Timestamp : 1611245624.688024
2021-01-21 16:13:44,691 DEBUG    RFM2Pi     2 From Node : 5
2021-01-21 16:13:44,691 DEBUG    RFM2Pi     2    Values : [-790, -23, -813, 238.44, 0, 0, 0, 0, 0, 0, 57596]
2021-01-21 16:13:44,692 DEBUG    RFM2Pi     2 Sent to channel(start)' : ToEmonCMS
2021-01-21 16:13:44,693 DEBUG    RFM2Pi     2 Sent to channel(end)' : ToEmonCMS
2021-01-21 16:13:44,964 DEBUG    MQTT       Publishing: emon/emonpi/power1 -790
2021-01-21 16:13:44,966 DEBUG    MQTT       Publishing: emon/emonpi/power2 -23
2021-01-21 16:13:44,968 DEBUG    MQTT       Publishing: emon/emonpi/power1pluspower2 -813
2021-01-21 16:13:44,970 DEBUG    MQTT       Publishing: emon/emonpi/vrms 238.44
2021-01-21 16:13:44,972 DEBUG    MQTT       Publishing: emon/emonpi/t1 0
2021-01-21 16:13:44,974 DEBUG    MQTT       Publishing: emon/emonpi/t2 0
2021-01-21 16:13:44,976 DEBUG    MQTT       Publishing: emon/emonpi/t3 0
2021-01-21 16:13:44,978 DEBUG    MQTT       Publishing: emon/emonpi/t4 0
2021-01-21 16:13:44,979 DEBUG    MQTT       Publishing: emon/emonpi/t5 0
2021-01-21 16:13:44,981 DEBUG    MQTT       Publishing: emon/emonpi/t6 0
2021-01-21 16:13:44,982 DEBUG    MQTT       Publishing: emon/emonpi/pulsecount 57596
2021-01-21 16:13:44,984 INFO     MQTT       Publishing 'node' formatted msg
2021-01-21 16:13:44,984 DEBUG    MQTT       Publishing: emonhub/rx/5/values -790,-23,-813,238.44,0,0,0,0,0,0,57596
2021-01-21 16:13:49,642 DEBUG    RFM2Pi     3 NEW FRAME : OK 5 234 252 233 255 211 252 44 93 0 0 0 0 0 0 0 0 0 0 0 0 0 225 0 0 (-0)
2021-01-21 16:13:49,645 DEBUG    RFM2Pi     3 Timestamp : 1611245629.642466
2021-01-21 16:13:49,645 DEBUG    RFM2Pi     3 From Node : 5
2021-01-21 16:13:49,646 DEBUG    RFM2Pi     3    Values : [-790, -23, -813, 238.52, 0, 0, 0, 0, 0, 0, 57600]
2021-01-21 16:13:49,647 DEBUG    RFM2Pi     3 Sent to channel(start)' : ToEmonCMS
2021-01-21 16:13:49,647 DEBUG    RFM2Pi     3 Sent to channel(end)' : ToEmonCMS
2021-01-21 16:13:49,757 DEBUG    MQTT       Publishing: emon/emonpi/power1 -790
2021-01-21 16:13:49,758 DEBUG    MQTT       Publishing: emon/emonpi/power2 -23
2021-01-21 16:13:49,760 DEBUG    MQTT       Publishing: emon/emonpi/power1pluspower2 -813
2021-01-21 16:13:49,761 DEBUG    MQTT       Publishing: emon/emonpi/vrms 238.52
2021-01-21 16:13:49,762 DEBUG    MQTT       Publishing: emon/emonpi/t1 0
2021-01-21 16:13:49,764 DEBUG    MQTT       Publishing: emon/emonpi/t2 0
2021-01-21 16:13:49,765 DEBUG    MQTT       Publishing: emon/emonpi/t3 0
2021-01-21 16:13:49,766 DEBUG    MQTT       Publishing: emon/emonpi/t4 0
2021-01-21 16:13:49,768 DEBUG    MQTT       Publishing: emon/emonpi/t5 0
2021-01-21 16:13:49,769 DEBUG    MQTT       Publishing: emon/emonpi/t6 0
2021-01-21 16:13:49,771 DEBUG    MQTT       Publishing: emon/emonpi/pulsecount 57600
2021-01-21 16:13:49,772 INFO     MQTT       Publishing 'node' formatted msg
2021-01-21 16:13:49,773 DEBUG    MQTT       Publishing: emonhub/rx/5/values -790,-23,-813,238.52,0,0,0,0,0,0,57600
2021-01-21 16:13:53,877 DEBUG    RFM2Pi     5 NEW FRAME : OK 23 56 0 0 0 158 3 31 0 1 0 0 0 (-65)
2021-01-21 16:13:53,880 DEBUG    RFM2Pi     5 Timestamp : 1611245633.877559
2021-01-21 16:13:53,881 DEBUG    RFM2Pi     5 From Node : 23
2021-01-21 16:13:53,881 DEBUG    RFM2Pi     5    Values : [5.6000000000000005, 0, 92.60000000000001, 3.1, 1]
2021-01-21 16:13:53,882 DEBUG    RFM2Pi     5      RSSI : -65
2021-01-21 16:13:53,882 DEBUG    RFM2Pi     5 Sent to channel(start)' : ToEmonCMS
2021-01-21 16:13:53,883 DEBUG    RFM2Pi     5 Sent to channel(end)' : ToEmonCMS
2021-01-21 16:13:54,114 DEBUG    MQTT       Publishing: emon/emonth5/temperature 5.6000000000000005
2021-01-21 16:13:54,115 DEBUG    MQTT       Publishing: emon/emonth5/external temperature 0
2021-01-21 16:13:54,117 DEBUG    MQTT       Publishing: emon/emonth5/humidity 92.60000000000001
2021-01-21 16:13:54,118 DEBUG    MQTT       Publishing: emon/emonth5/battery 3.1
2021-01-21 16:13:54,120 DEBUG    MQTT       Publishing: emon/emonth5/pulsecount 1
2021-01-21 16:13:54,121 DEBUG    MQTT       Publishing: emon/emonth5/rssi -65
2021-01-21 16:13:54,122 INFO     MQTT       Publishing 'node' formatted msg
2021-01-21 16:13:54,123 DEBUG    MQTT       Publishing: emonhub/rx/23/values 5.6000000000000005,0,92.60000000000001,3.1,1,-65
2021-01-21 16:13:54,693 DEBUG    RFM2Pi     6 NEW FRAME : OK 5 234 252 231 255 209 252 25 93 0 0 0 0 0 0 0 0 0 0 0 0 3 225 0 0 (-0)
2021-01-21 16:13:54,695 DEBUG    RFM2Pi     6 Timestamp : 1611245634.692925

You could try putting it back the other way, it is best to make changes one at a time. Although we did see the failure with the symlink in place so I’m not sure it will work.

@TrystanLea has also made some other changes since and the debug line that was previously being reached (but failing) is no longer there so we can’t easily compare

I think the issue might be in this bit as anywhere else leads to an error message or exception

                            for i in read_keys:
                                if i in r:
                                    c.names.append(self._SDM120_settings['prefix']+read_keys[i][0])
                                    c.realdata.append(round(r[i],read_keys[i][1]))

comparing keys with strings?? I don’t know what the raw r is like.

Thanks @srt, that’s a pain, I’m sure I remember seeing the key error voltage error in you earlier post before, but cant remember now how I solved it or what the reason was.

I have the latest code running and working well on my SDM120 here, so I dont think its that code necessarily.

You could try running this code manually @srt

import sdm_modbus, time

device = sdm_modbus.SDM120(device="/dev/ttyUSB0", baud=2400)

last_reading = 0

while True:

    if (time.time()-last_reading)>=10.0:
        last_reading = time.time()
    
        if device.connected():
            r = device.read_all(sdm_modbus.registerType.INPUT)
            for i in r:
                print(i+" "+str(r[i]))
            # print ("%f %f %f %f %f" % (r['voltage'],r['power_active'],r['power_factor'],r['frequency'],r['import_energy_active']))
            
    time.sleep(0.1) 

Create a file called sdm120.py and copy the contents into that file:

nano sdm120.py (right click and then paste)

Run the script with:

python3 sdm120.py
1 Like

You may need to stop emonhub first:

sudo service emonhub stop