Jun 192016
 

Wouldn’t it be cool if you could monitor your electricity usage with OpenHAB for less than 20 bucks with the same accuracy your power company uses for billing?

Using an inexpensive rtl-sdr dongle, it’s possible to listen for signals from ERT compatible smart meters using rtlamr. This script runs as a daemon, launches rtl_tcp and rtlamr, and parses the output from rtlamr. If this matches your meter, it will push the data into OpenHAB using the REST API.

Turns out these ERT meters (at least in Omaha) are broadcasting 4 hours of usage data with 5 minute resolution. It broadcasts this data every minute, repeating the previous broadcast until the next 5 minute interval has completed. This data is flying around unprotected. Using free software and an inexpensive SDR dongle it’s possible to pull this data into OpenHAB.

rtlamr does all the heavy lifting here. It listens for the data, decodes, and passes along the meter readings.

On my meter, the interesting information is just above the readout. That’s my meter’s type and endpoint ID or serial number. I’ve blurred my details for privacy.

meter2

You can check your meter’s compatibility on the meters list on the rtlamr project page

The hardware required isn’t very bulky, I’ve got it attached to an old computer that also runs my OpenHAB server. I got mine on amazon, there are a lot of them available. Just search for RTL2832U

server

I’m looking at IDM Interval Data Message because my usage over the previous 5 minute interval is one of the most important datapoints for changing my usage. The first differential consumption is my most recent 5 minute period, and the last consumption field is my current meter reading. Interestingly, my meter shows 5 digits on the front, but the rtlamr data has 7 digits. This gives me hundredths of a kilowatt hour.

Keeping this front and center on the home automation dashboard on the wall mounted android tablets makes me more mindful of our power usage.

tablet-power

Checking on OPPD rates, in the summer, it’s 11.24 cents per kilowatt hour

Looking more closely at usage, the air conditioning is my biggest use by far.

Quick overview of how this actually works

  • Meter broadcasts usage with 5 minute interval data
  • rtl sdr dongle recieves it
  • rtlamr detects decodes and parses it
  • data is then passed to my script which only sends part of the data to OpenHAB through the REST API
  • This updates the first 4 items in the power items group
  • The rules then calculate my usage from data in OpenHAB’s mysql persistence
  • And update the rest of the items
  • Then I see the numbers and dial back the AC

Requirements

rtl-sdr installed
http://sdr.osmocom.org/trac/wiki/rtl-sdr

Set dongle serial number with rtl-eeprom
http://manpages.ubuntu.com/manpages/trusty/man1/rtl_eeprom.1.html

install Go programming language & set gopath

sudo apt-get install golang

https://golang.org/doc/code.html#GOPATH

install rtlamr

go get github.com/bemasher/rtlamr

https://github.com/bemasher/rtlamr

install perl packages

sudo apt-get install libwww-mechanize-perl libfile-pid-perl

Install

Start by downloading as a zip and extracting, or git clone https://github.com/ragingcomputer/amridm2openhab

The script needs some configuration, see the configuration section starting around line 60

Advertisement:
## Configuration
my $port          = 1234;                       # port for rtl_tcp to listen on
my $address       = "192.168.1.100";            # bind address for rtl_tcp. 
                                                # Can be 127.0.0.1 or actual address of your server
my $dongleSerial  = "00000011";                 # serialnumber set by rtl_eeprom
my $rtltcp        = "/usr/local/bin/rtl_tcp";   # path to rtl_tcp
my $rtlamr        = "/opt/gopath/bin/rtlamr";   # path to rtlamr
my $rtleeprom     = "/usr/local/bin/rtl_eeprom" # path to rtl_eeprom
my $meterSerial   = "5XXXXXX3";                 # meter serial number, likely on the front of your meter
                                                # used to filter results to just your meter
my $openhabServer = "http://username:password\@127.0.0.1:8080"; # URL of OpenHAB server. 
# Be mindful of the \ escaping the @ sign for basic auth. 
# If you aren't using auth, just enter the URL similar to http://127.0.0.1:8080

create log file and set permissions

sudo touch /var/log/amridm2openhab.log
sudo chmod 644 /var/log/amridm2openhab.log
sudo chown root:adm /var/log/amridm2openhab.log

copy perl script into /usr/sbin and set executable

sudo cp amridm2openhab /usr/sbin/amridm2openhab
sudo chmod +x /usr/sbin/amridm2openhab

copy initscript into init.d and set executable

sudo cp initscript-amridm2openhab /etc/init.d/amridm2openhab
sudo chmod +x /etc/init.d/amridm2openhab

set initscript to start and start

update-rc.d amridm2openhab defaults 99
sudo service amridm2openhab start

Optional, watch log file to verify it has started

tail -f /var/log/amridm2openhab.log

It doesn’t do any good if you haven’t configured the items and the rules in OpenHAB.

power.items

/* Power Data from RTL-AMR */
Group gPowerMeterData
Number PowerMeterIntervalNum         "Interval [%s]"                          (gPowerMeterData)
Number PowerMeterLastInterval        "Last Interval Consumption [%s]"         (gPowerMeterData)
Number PowerMeterLastIntervalAverage "Last Interval Average Consumption [%s]" (gPowerMeterData)
Number PowerMeterConsumption         "Consumption [%s]"                       (gPowerMeterData)
Number Power2DaysAgoUsage            "2 Days Ago [%.2f KWH]"                  (gPowerMeterData)
Number Power2DaysAgoCost             "2 Days Ago [$%.2f]"                     (gPowerMeterData)
Number PowerYesterdayUsage           "Yesterday [%.2f KWH]"                   (gPowerMeterData)
Number PowerYesterdayCost            "Yesterday [$%.2f]"                      (gPowerMeterData)
Number PowerTodayUsage               "Today [%.2f KWH]"                       (gPowerMeterData)
Number PowerTodayCost                "Today [$%.2f]"                          (gPowerMeterData)

power.rules

rule "Update Power Costs"
when
    Item  PowerMeterConsumption received update
then
    // http://www.oppd.com/residential/residential-rates/
    // Summer (June 1 – Sept. 30)  - 11.42 cents/kWh for all kWh
    var Number midnightReading
    var Number yesterdayMidnightReading
    var Number days2agoMidnightReading
    var Number currentReading
    var Number days2agoUsageKWH
    var Number yesterdayUsageKWH
    var Number todayUsageKWH
    var Number yesterdayCost
    var Number days2agoCost
    var Number todayCost
    var Number KWHCost = 0.1142

    if (PowerMeterConsumption.state instanceof DecimalType) {
        
        days2agoMidnightReading = (PowerMeterConsumption.historicState(now.toDateMidnight.minusDays(2), "mysql").state as DecimalType)
        yesterdayMidnightReading = (PowerMeterConsumption.historicState(now.toDateMidnight.minusDays(1), "mysql").state as DecimalType)
        midnightReading = (PowerMeterConsumption.historicState(now.toDateMidnight, "mysql").state as DecimalType)
        currentReading = PowerMeterConsumption.state as DecimalType
        
        days2agoUsageKWH = ((yesterdayMidnightReading - days2agoMidnightReading)/100)
        yesterdayUsageKWH = ((midnightReading - yesterdayMidnightReading)/100)
        todayUsageKWH = ((currentReading - midnightReading)/100)
        days2agoCost = days2agoUsageKWH*KWHCost
        yesterdayCost = yesterdayUsageKWH*KWHCost
        todayCost = todayUsageKWH*KWHCost
 
        postUpdate(PowerTodayUsage, todayUsageKWH)
        postUpdate(PowerTodayCost, todayCost)
               
        postUpdate(PowerYesterdayUsage, yesterdayUsageKWH)
        postUpdate(PowerYesterdayCost, yesterdayCost)

        postUpdate(Power2DaysAgoUsage, days2agoUsageKWH)
        postUpdate(Power2DaysAgoCost, days2agoCost)
        
        
    }
end

power portion of sitemap

Text label="AMR Power Meter" {
    Text item=PowerMeterIntervalNum
    Text item=PowerMeterLastInterval
    Text item=PowerMeterLastIntervalAverage
    Text item=PowerMeterConsumption
    Text item=PowerTodayCost
    Text item=PowerTodayUsage
    Text item=PowerYesterdayCost
    Text item=PowerYesterdayUsage
    Text item=Power2DaysAgoCost
    Text item=Power2DaysAgoUsage
    Chart item=PowerMeterLastInterval period=4h refresh=10000
    Chart item=PowerMeterLastInterval period=D refresh=10000
    Chart item=PowerMeterLastInterval period=W refresh=10000
}

 Leave a Reply

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

(required)

(required)