Open Energy Monitor

Others (MiLight, Hue, Toon etc...)

Moderator: leecollings

Rene
Posts: 18
Joined: Tuesday 23 December 2014 2:07
Target OS: Raspberry Pi / ODroid
Domoticz version:
Contact:

Open Energy Monitor

Post by Rene »

Hi,

Is there anyone working on the Open Energy Monitor? I ordered this energy monitor V3 with 4 CTs. I want to make my own driver for the RFM12b so that I dont need to interface with the RFM12Pi which looks like an extra step to me. Why can't a 600 Mhz 32 bit processor (Or 1000 Mhz Beagle Bone Black) take on a job of a 8 Mhz 8 bit MPU? Anyway all I want to know if anyone is interrested in helping me. I looked into other Energy Meters but they are all 1 phase or 3 phased based and here in Canada residential we have 2 phase 120V also the Open Energy Monitor is nicely priced compared to commercial versions..

Cheers Rene,
Attachments
RF12 module strapped to Beagle Bone Black
RF12 module strapped to Beagle Bone Black
image1(1).JPG (97.78 KiB) Viewed 10474 times
Rene
Posts: 18
Joined: Tuesday 23 December 2014 2:07
Target OS: Raspberry Pi / ODroid
Domoticz version:
Contact:

Re: Open Energy Monitor

Post by Rene »

Ok I got a bit futher with this. I created a Python Scripts that will read the data directly from a RFM12B chip into my BeagleBoneBlack. I am not using the nIRQ line from the chip but use polling which makes the BBB very busy. But it does give me data so I am very pleased. The origional project uses a RaspberryPi board with its on ATMEGA Micro Chip on board.

Steps to get this to work.

1. Make connections between RFM12B and your processor board (In my case BeagleBoneBlack)
2. install spidev
3. install requests
4. enable spi interface (this requires some steps on the BeagleBoneBlack)
5. create 4 energy meters in Domoticz and fill in their IDX values in the script.
6. Execute by python <script>.py &

Things I want to add:

1. Add Temp sensor.
2. Add Vrms value.
3. Auto create devices and idx values

Code: Select all

#!/usr/bin/python 
#
#		Script to read Open Energy Monitor.
#   	And publish these to domoticz software.
#
#		(C)reated by Rtm-soft Jan 2015
#	
#		This code is Free Software and comes with absolutely
#		no warranty and may freely be modified and distributed.


#Modules used in this program

import time							#For the usual naps
import spidev						#SPI interface
import requests						#To publisch data to Domoticz
import json							#For writing index values to file

DOMOTICZ_URL = "http://localhost:8080"	#http://<username:password@>domoticz-ip<:port>
IDX = ['61','60','59','58']				#Index for the 4 energy meters. Change these to yours

#SPI interface(s) on Beagle Bone Black
#PORT	CS0		DO		DI		SCLK	nIRQ
#SPI0	P9_17	P9_21 	P9_18 	P9_22	P9_16 (GPIO_51)
#SPI1	P9_28	P9_29	P9_30	P9_31	P9_27 (GPIO_115)	This interface can not be used with HDMI enabled!

#RF12 command codes
RF_RECV_CONTROL=[0x94,0xA0]
RF_RECEIVER_ON=[0x82,0xDD]
RF_XMITTER_ON=[0x82,0x3D]
RF_RX_FIFO_READ=[0xB0,0x00]
RF_IDLE_MODE=[0x82,0x0D]

GROUP = 210		#210 Group used for Open Energy Monitor
NODE = 10		#Default node for Open Energy Monitor
CR = 1.91		#Voltage correction. 1.91 for America and 1 for World.
polynomial = 0xA001

def crc16_update(crc, value) :
	for bit in range(8) :
		xor = (crc ^ (value >> bit)) & 1
		crc >>= 1
		if xor :
			crc ^= polynomial
	return crc
	
def init_RF12() :
	spi.writebytes([0x00,0x00])	# initial SPI transfer added to avoid power-up problem
	time.sleep (5)				# Give RFM12B time to boot up
	spi.writebytes([0x00,0x00])
	spi.writebytes([0x80,0xD7])	#REG 1 EL (ena TX), EF (ena RX FIFO), 12.0pF
	spi.writebytes([0xA6,0x40])	#REG 3 96-3960 freq range of values within band
	spi.writebytes([0xC6,0x06])	#REG 4 approx 49.2 Kbps, i.e. 10000/29/(1+6) Kbps
	spi.writebytes([0x94,0xA2])	#REG 5 VDI,FAST,BW=134kHz,0dBm,-91dBm
	spi.writebytes([0xC2,0b11101100])#REG 6 AL,!ml,DIG,DQD4
	if (GROUP != 0) :
		spi.writebytes([0xCA,0x83])#REG 7 0x83 FIFO8,2-SYNC,!ff,!DR
		spi.writebytes([0xCE,GROUP])#SYNC=2DXX
	else :
		spi.writebytes([0xCA,0x8B])#REG 7 0x8B FIFO8,1-SYNC,!ff,!DR
		spi.writebytes([0xCE,0x2D])#SYNC=2D
	spi.writebytes([0xC4,0x83])	#REG 9 @PWR,NO RSTRIC,!st,!fi,OE,EN
	spi.writebytes([0x98,0x50])	#!mp,90kHz,MAX OUT
	spi.writebytes([0xCC,0x77])	#PLL Setting Command
	spi.writebytes([0xE0,0x00])	#REG 12 Wake-Up Timer Command. Disabled
	spi.writebytes([0xC8,0x00])	#REG 13 Low Duty-Cycle Command. Disabled
	spi.writebytes([0xC0,0x49])	#REG 14 1.66MHz,3.1V

def get_idx() :					#Get domoticz object indexes, if they dont exists created the 4 objects in or case Energy meters
	inputfile = 'oemidx.txt'	#Assuming it is in the same directory as this script
	try :
		f = open(inputfile)
		idx = json.load(f)		#Read index values from file
	except IOError :			#File didn't exist. Create new one.
		f = open(inputfile, 'w')
		json.dump(IDX, f)		#Write domoticz indexes to file.
	f.close()
	return(idx)	

#Main
spi = spidev.SpiDev()
spi.open(2,0)					#Open SPI1 interface with CS0 low
spi.bits_per_word=8 			#Couldn't get 16bits to work..
spi.mode=0						#SPI mode.
spi.max_speed_hz=8000000		#SPI speed, RFM12B max clock 20 MHz (50ns clock cycle)
packetsize=16					#We are expecting  16 bytes from EmonTx V3.4.
init_RF12()						#Set up our RFM12B for receiving
spi.max_speed_hz=2500000 		#Slow down for FIFO read. Fref/4
idx=get_idx()					#Get and if not exist create index values for energy meters
joules=[0]*4 					#Watt seconds for CT 1 to 4
watt=[0]*4						#Watts measured by CTs
data=[0]*packetsize				#Make a data buffer
lasttime=time.time()			#Last time sinds measurement	

try:
	while True:
		spi.writebytes(RF_RECEIVER_ON)		#Start Receiving. Look for sync signal
		crc=crc16_update(0xFFFF,GROUP)		#Start CRC calculation with GROUP byte
		for n in range(packetsize) :
			while not (spi.xfer([0x00])[0] & 0x80) : pass	#FFIT flag set. Fifo bits reached preset level
			data[n]=spi.xfer([0xB0,0x00])[1]#Read Fifo. 8 bits = 1 byte.
			crc=crc16_update(crc,data[n])	#[0xAA,0xAA,0xAA,0x2D]+. When I start at GROUP my CRC ends with 0.
		spi.writebytes(RF_IDLE_MODE)		#Stop Receiving
		if crc==0 :							#Payload is data integrity checked and OK
			#Calculate wattage and publisch the data to domoticz for all 4 CTs. CR is the voltage correction.Here in Canada we use 120V.
			if (data[0]==NODE) : #Only take data from our node
				watt[0] = (data[2]+(data[3]<<8))/CR		#Calculate wattage at this moment. data[2] is LSB and data[3] is MSB 
				watt[1] = (data[4]+(data[5]<<8))/CR
				watt[2] = (data[6]+(data[7]<<8))/CR
				watt[3] = (data[8]+(data[9]<<8))/CR
				currenttime = time.time()	#How much time has passed since last measurement
				for n, wattage in enumerate(watt) :
					joules[n] += (currenttime-lasttime)*wattage  #Calculate wattage used between now and last measurement
					url= DOMOTICZ_URL+"/json.htm?type=command&param=udevice&idx="+idx[n]+"&nvalue=0&svalue="+str(wattage)+";"+str(joules[n]/3600) #Convert W/s to kWh
					requests.get(url)	
				lasttime=currenttime
				time.sleep(11)	#EmonTX will  only output every 10 seconds (More like 12 seconds). So dont waste time polling.

except KeyboardInterrupt:							# Ctrl+C pressed, so...
	spi.close()

cosmo61
Posts: 6
Joined: Tuesday 17 February 2015 11:03
Target OS: Raspberry Pi / ODroid
Domoticz version:
Location: Sweden
Contact:

Re: Open Energy Monitor

Post by cosmo61 »

Hi!
Nice project!
I have also an energy monitor V3.
My first thoughts was to use the monitor separately on a dedicated Raspberry Pi apart from Domoticz,
but then I saw your nice project.
My question is? Is it hard to adapt your script to Raspberry Pi ?
I'm not a Python programmer :D
Rene
Posts: 18
Joined: Tuesday 23 December 2014 2:07
Target OS: Raspberry Pi / ODroid
Domoticz version:
Contact:

Re: Open Energy Monitor

Post by Rene »

cosmo61 wrote:Hi!
Nice project!
I have also an energy monitor V3.
My first thoughts was to use the monitor separately on a dedicated Raspberry Pi apart from Domoticz,
but then I saw your nice project.
My question is? Is it hard to adapt your script to Raspberry Pi ?
I'm not a Python programmer :D
No the python script should also work on your Raspberry Pi. Try it, see if it gives you any errors and report back. Then we will figure out what needs to be done next. But follow the steps that I wrote down. With some Googling you should find al answers..

Cheers Rene
pfer10
Posts: 9
Joined: Sunday 08 February 2015 16:27
Target OS: Linux
Domoticz version:
Contact:

Re: Open Energy Monitor

Post by pfer10 »

Just wondering what CTs you went with? I looked at Open Energy Monitor but as you said they are setup more for single phase or 3 phase. I couldn't find a CT for 100 amp per phase 2 phase service like we have here in North America.

I used the Aeon labs HEM through zwave but I am finding the kw reading off if the power factor isn't close to 1. I think the open energy monitor does real power so I should get much better results and as you said they are much more flexible. The last HEM I went with was Ver 1 and they are selling cheap. Might be a way to get a couple more CTs for cheap and adapt them to the Open Energy Monitor board.
cosmo61
Posts: 6
Joined: Tuesday 17 February 2015 11:03
Target OS: Raspberry Pi / ODroid
Domoticz version:
Location: Sweden
Contact:

Re: Open Energy Monitor

Post by cosmo61 »

Hi!
I have setup a Raspberry pi B+ with latest domoticz image.
Raspberry Pi Details:
Type: Model B+, Revision: 1.2, Memory: 512MB
ls /dev/spidev*
/dev/spidev0.0 /dev/spidev0.1

Code: Select all

udo raspi-config
Advance option SPI Enable Serial enable I2c enable

sudo apt-get install python-rpi.gpio  python-dev sudo apt-get install python-requests


sudo apt-get install minicom

sudo nano /etc/inittab
# T0:23:respawn:/sbin/getty -L ttyAMA0 115200 vt100

sudo nano /boot/cmdline.txt
dwc_otg.lpm_enable=0 console=tty1 root=/dev/mmcblk0p2 rootfstype=ext4 elevator=deadline rootwait

sudo wget https://raw.github.com/lurch/rpi-serial-console/master/rpi-serial-console -O /usr/bin/rpi-serial-console && sudo chmod +x /usr/bin/rpi-serial-console
 sudo rpi-serial-console disable
 sudo reboot
 mkdir python-spi
cd python-spi
wget https://raw.github.com/doceme/py-spidev/master/setup.py
wget https://raw.github.com/doceme/py-spidev/master/spidev_module.c
sudo python setup.py install
sudo chmod 666 /dev/spidev0.0

minicom -b9600 -D/dev/ttyAMA0
Current configuration:
64 i0 g2 @ 433 MHz Lock: 1
Test working!
rpi-serial-console disable
changed spi.open(2,0) to spi.open(0,0)
Changed IDX and electric current to 230V
CR=1
Running sudo python yourscript.py
And it,s running but nothing happened.
You must break with ctrl-c, ´can you run it with debug-mode ?
Thank You!
Rene
Posts: 18
Joined: Tuesday 23 December 2014 2:07
Target OS: Raspberry Pi / ODroid
Domoticz version:
Contact:

Re: Open Energy Monitor

Post by Rene »

pfer10 wrote:Just wondering what CTs you went with? I looked at Open Energy Monitor but as you said they are setup more for single phase or 3 phase. I couldn't find a CT for 100 amp per phase 2 phase service like we have here in North America.

I used the Aeon labs HEM through zwave but I am finding the kw reading off if the power factor isn't close to 1. I think the open energy monitor does real power so I should get much better results and as you said they are much more flexible. The last HEM I went with was Ver 1 and they are selling cheap. Might be a way to get a couple more CTs for cheap and adapt them to the Open Energy Monitor board.
I am using the same ones as you can buy at Open Energy Monitors website. But I ordered them from Aliexpress.com. This is the suplier I got them from..Delivery was fast..

http://www.aliexpress.com/item/2pcs-Lot ... 12729.html

The software that is default in the Open Energy Monitor V3.4 seems fine for North America. I have 2 CT on my main panel en 2 CTs on my basement sub panel. One around the black and one around the red wire. The power values reported by the software seem to make sence except for the the CTs measure current and not power. So power equels current times voltage. The V3.4 software uses 230V if you dont use the transformer. So I built in a correction factor 230/120v. Of course I could change the firmware in the OEM but i dont have a programmer. So it is easy done with the python script

Hope this answers your questions.. Rene
Rene
Posts: 18
Joined: Tuesday 23 December 2014 2:07
Target OS: Raspberry Pi / ODroid
Domoticz version:
Contact:

Re: Open Energy Monitor

Post by Rene »

cosmo61 wrote:Hi!
I have setup a Raspberry pi B+ with latest domoticz image.
Raspberry Pi Details:
Type: Model B+, Revision: 1.2, Memory: 512MB
ls /dev/spidev*
/dev/spidev0.0 /dev/spidev0.1

Code: Select all

udo raspi-config
Advance option SPI Enable Serial enable I2c enable

sudo apt-get install python-rpi.gpio  python-dev sudo apt-get install python-requests


sudo apt-get install minicom

sudo nano /etc/inittab
# T0:23:respawn:/sbin/getty -L ttyAMA0 115200 vt100

sudo nano /boot/cmdline.txt
dwc_otg.lpm_enable=0 console=tty1 root=/dev/mmcblk0p2 rootfstype=ext4 elevator=deadline rootwait

sudo wget https://raw.github.com/lurch/rpi-serial-console/master/rpi-serial-console -O /usr/bin/rpi-serial-console && sudo chmod +x /usr/bin/rpi-serial-console

 sudo rpi-serial-console disable
 sudo reboot
 mkdir python-spi
cd python-spi
wget https://raw.github.com/doceme/py-spidev/master/setup.py
wget https://raw.github.com/doceme/py-spidev/master/spidev_module.c
sudo python setup.py install
sudo chmod 666 /dev/spidev0.0

minicom -b9600 -D/dev/ttyAMA0
Current configuration:
64 i0 g2 @ 433 MHz Lock: 1
Test working!
rpi-serial-console disable
changed spi.open(2,0) to spi.open(0,0)
Changed IDX and electric current to 230V
CR=1
Running sudo python yourscript.py
And it,s running but nothing happened.
You must break with ctrl-c, ´can you run it with debug-mode ?
Thank You!
Couple of things you can do. Put a print data line just above if crc == 0 line. This will print a line with the received data. If your reception is good you will see a pattern. The other thing you can do is to install spi-test just google how to do that. You should see some data come by. If you only see ffs your spi interface doesnt see the rfm 12 module make sure you have the right spi port. Also open(0,0) is spi port 0 with cs0 active so maybe you used cs1 on the Pi in that case use open (0,1). The code is for the RFM12 module not for the RFM69 Ok. Let me know if this helps you along..I do not see a reason why it would not work on the Raspberry Pi.

Greetings Rene
ThinkPad
Posts: 890
Joined: Tuesday 30 September 2014 8:49
Target OS: Linux
Domoticz version: beta
Location: The Netherlands
Contact:

Re: Open Energy Monitor

Post by ThinkPad »

On this Dutch forum they are also reading data from a energy monitor with the RFM12 and a Raspberry Pi: http://gathering.tweakers.net/forum/lis ... es/1623766
I don't know if you are Dutch (you haven't filled in your location, please do so) so don't know if you can use it :P
I am not active on this forum anymore.
cosmo61
Posts: 6
Joined: Tuesday 17 February 2015 11:03
Target OS: Raspberry Pi / ODroid
Domoticz version:
Location: Sweden
Contact:

Re: Open Energy Monitor

Post by cosmo61 »

Okey thanks!
Shall try the Open Energy Monitor, again later in this week.
I think it's a problem with quote messages, the location disappear when I use it.
Dutch is little hard to understand! for a Swedish guy :), but thank's anyway. You can always use google translate. :D
Rene
Posts: 18
Joined: Tuesday 23 December 2014 2:07
Target OS: Raspberry Pi / ODroid
Domoticz version:
Contact:

Re: Open Energy Monitor

Post by Rene »

cosmo61 wrote:Okey thanks!
Shall try the Open Energy Monitor, again later in this week.
I think it's a problem with quote messages, the location disappear when I use it.
Dutch is little hard to understand! for a Swedish guy :), but thank's anyway. You can always use google translate. :D
I have a Pi B laying around and I have another RFM12 on order which should be in by now (I am not home right now but will be by Wednesday) when I get home I will try to hook it up on my Pi B. See what needs to be done to make it work. It should not be that hard. All i can see what can go wrong is distance to your transmittor and controlling the spi interface on the Pi. If the code runs without errors is a good sign. I will keep you up to date.

cheers Rene
cosmo61
Posts: 6
Joined: Tuesday 17 February 2015 11:03
Target OS: Raspberry Pi / ODroid
Domoticz version:
Location: Sweden
Contact:

Re: Open Energy Monitor

Post by cosmo61 »

Rene wrote:
cosmo61 wrote:Okey thanks!
Shall try the Open Energy Monitor, again later in this week.
I think it's a problem with quote messages, the location disappear when I use it.
Dutch is little hard to understand! for a Swedish guy :), but thank's anyway. You can always use google translate. :D
I have a Pi B laying around and I have another RFM12 on order which should be in by now (I am not home right now but will be by Wednesday) when I get home I will try to hook it up on my Pi B. See what needs to be done to make it work. It should not be that hard. All i can see what can go wrong is distance to your transmittor and controlling the spi interface on the Pi. If the code runs without errors is a good sign. I will keep you up to date.

cheers Rene
Thank's it's sounds great. :D
In The Py program u use SPI connection. If I understand this correct, you have to connect RFM12Pi V2 to (3.3v) pin 17 and etc?
RFM12B !! not RFM12Pi V2 (serial interface), my mistake!
would the Raspberry Pi connection to RFM12B be something like this?
Is it okej to use GPIO_22 ?

corrected
CE0 -> nSEL
GND -> GND
SCLK -> SCK
MISO -> SDO
MOSI -> SDI
3,3V -> VCC
#GPIO_22 -> IRQ
PIN 15, 17,19,21,23,25


see the attachments!
Attachments
RFM12.png
RFM12.png (49.78 KiB) Viewed 9972 times
rpi pin.png
rpi pin.png (192.03 KiB) Viewed 10082 times
Last edited by cosmo61 on Saturday 14 March 2015 11:06, edited 7 times in total.
Rene
Posts: 18
Joined: Tuesday 23 December 2014 2:07
Target OS: Raspberry Pi / ODroid
Domoticz version:
Contact:

Re: Open Energy Monitor

Post by Rene »

Yes lovely those MISO and MOSI terminology. Master Input Slave Output=MISO I would say goes to SDO on the RFM12B and MOSI then to SDI (Reverse from what you wrote!). I am not using the IRQ line from the chip. I found that it was to slow (Python couldnt keep up with it). That is the reason why I want to use the RFM69 (better reception and larger data buffer, same price). Ok my chips are in so is my 1 wire temp sensor that I want to hook up to the OEM V3.4. So I will let you know more details later..

Cheers Rene
cosmo61
Posts: 6
Joined: Tuesday 17 February 2015 11:03
Target OS: Raspberry Pi / ODroid
Domoticz version:
Location: Sweden
Contact:

Re: Open Energy Monitor

Post by cosmo61 »

Yes this is like a new world for me, with RFM12B, RFM01 etc.
But it's very fun. :D

I was reading about the WH1081 weather sensors with RFM01 , so
it can be many new project's in future!
Rene
Posts: 18
Joined: Tuesday 23 December 2014 2:07
Target OS: Raspberry Pi / ODroid
Domoticz version:
Contact:

Re: Open Energy Monitor

Post by Rene »

Ok update so far, hooked up RFM12B chip to Raspberry Pi. You are missing the Chip Enable 0 line in your diagram! It needs to be hooked up to pin 24. And the MOSI does go to SDI on the RFM12B module. Ok, so far this works but then the trouble starts. If I do a print data I get a couple of bytes fine [10,12,] but then it messes up. It looks like the Pi can't keep up with the data (which comes in at 44 kbit), my Beagle Bone Black had no issues. Not sure yet how to fix this speed problem, working on it right now. I might have to convert the program to a C version. I will keep you posted.
Rene
Posts: 18
Joined: Tuesday 23 December 2014 2:07
Target OS: Raspberry Pi / ODroid
Domoticz version:
Contact:

Re: Open Energy Monitor

Post by Rene »

Can't get the RFM12 chip to work on the Pi B (without going to C code). It reads a few bytes and the the rest of the bytes get overwritten before they can be read. Not sure if the faster Pi B 2 would perform better. My Beagle Bone Black has no problems. But I moved on and I now own a RFM69 chip. This chip is the same price as the other, except its properties are much better. Better sensitivity and a 66 byte FIFO instead of 1 byte on the RFM12. The Open Energy Monitor sends a packet of 16 bytes, so the whole package will fit in the FIFO and I am hoping no bytes will be lost before they can be read by the Pi. First test is promising. I will be publishing the code for the RFM69 soon.
Rene
Posts: 18
Joined: Tuesday 23 December 2014 2:07
Target OS: Raspberry Pi / ODroid
Domoticz version:
Contact:

Open Energy Monitor

Post by Rene »

Here is the code to read the Open Energy Monitor V3.4 with a RFM69 module connected directly to the Raspberry Pi. It is interrupt based and does not ask for a lot of processing power. A few Python modules need to be preinstalled and the program needs to be run in sudo mode because it accesses the hardware (spi interface). The IDX values need to be changed for yours. Read the script file. Good luck..

Code: Select all

#!/usr/bin/python 
#
#		Script to read Open Energy Monitor.
#   	And publish these to domoticz software.
#
#		(C)reated by Rtm-soft Jan 2015
#	
#		This code is Free Software and comes with absolutely
#		no warranty and may freely be modified and distributed.


#Modules used in this program

import time							#For the usual naps
import spidev						#SPI interface
import requests						#To publisch data to Domoticz
import json							#For writing index values to file
import signal,sys					#For system shutdown detection
import RPi.GPIO as GPIO				#Module to read GPIO Ports.

#Global variable for shutdown
totals=[0]*5	 					#Watt seconds for CT 1 to 4 and their combined total

DOMOTICZ_URL = "http://192.168.11.16:8080"	#http://<username:password@>domoticz-ip<:port>
IDX = ['61','60','59','58','62','63','81']	#'64' Index for the 5 energy meters and Battery Voltage and Temp sensor. Change these to yours!
TOTALS = [0,0,0,0,0]						#Total of kWhs measured

#SPI interface(s) on Beagle Bone Black
#PORT	CS0		DO		DI		SCLK	IRQ
#SPI0	P9_17	P9_21 	P9_18 	P9_22	P9_16 (GPIO_51)
#SPI1	P9_28	P9_29	P9_30	P9_31	P9_27 (GPIO_115)	This interface can not be used with HDMI enabled!

#SPI interface(s) on Raspberry Pi
#PORT	CS0		CS1		MISO	MOSI	SCLK	DIO0
#SPI0	P1_24	P1_26	P1_21	P1_19	P1_23	P1_22 (GPIO_25).

#RFM69 command codes
RFM69_SLEEP=[0x81,0x00]
RFM69_STANDBY=[0x81,0x04]
RFM69_RECEIVER=[0x81,0x10]
RFM69_TRANSMITTER=[0x81,0x0C]

#Constants
GROUP = 210						#210 Group used for Open Energy Monitor
NODE = 10						#Default node for Open Energy Monitor
CR = 1.91						#Voltage correction. 1.91 for America and 1 for World.
POLYNOMIAL = 0xA001				#CRC16

#Variabeles
packetsize=16					#We are expecting  16 bytes from EmonTx V3.4.
watt=[0]*5						#Watts measured by CTs and their combined total
data=[0]*packetsize				#Make a data buffer
joules=[0]*5					#Joules used sinds last measurement
lasttime=time.time()			#Last time sinds measurement. Variable used in interrupt


def crc16_update(crc, value) :  #Calculate CCITT CRC .
	for bit in range(8) :
		xor = (crc ^ (value >> bit)) & 1
		crc >>= 1
		if xor :
			crc ^= POLYNOMIAL
	return crc

def init_RFM69() :
	spi.xfer2([0x81,0x04])	#OpMode = standby, SequencerOff
	spi.xfer2([0x82,0x00])	#DataModul = packet mode, fsk
	spi.xfer2([0x83,0x02])	#BitRateMsb, data rate = 49,261 khz
	spi.xfer2([0x84,0x8A])	#BitRateLsb, divider = 32 Mhz / 650
	spi.xfer2([0x85,0x05])	#FdevMsb = 90 kHz?BW=134kHz
	spi.xfer2([0x86,0xC3])	#FdevLsb = 90 KHz
	spi.xfer2([0x87,0x6C])	#FrfMsb, D9 freq = 868.000 MHz #6C 434.000Mhz
	spi.xfer2([0x88,0x80])	#FrfMib, 00 divider = 14221312 #80
	spi.xfer2([0x89,0x00])	#FrfLsb, 00 step = 61.03515625 #00
	spi.xfer2([0x8B,0x20])	#AfcCtrl, afclowbetaon
	spi.xfer2([0x99,0x42])	#RxBw ...
	spi.xfer2([0x9E,0x2C])	#FeiStart, AfcAutoclearOn, AfcAutoOn
	spi.xfer2([0xA5,0x40])	#DioMapping1 = DIO0 = Payload Ready (Rx)
	spi.xfer2([0xA9,0xDC])	#RssiThresh ...#
	spi.xfer2([0xAE,0x88])	#SyncConfig = sync on, sync size = 2
	spi.xfer2([0xAF,0x2D])	#SyncValue1 = 0x2D
	spi.xfer2([0xB0,GROUP])	#SyncValue2 = 0xD2=Group 210
	spi.xfer2([0xB7,0x02])	#PacketConfig1 = fixed, no crc, CRC filt off,check Node+Broadcast
	spi.xfer2([0xB8,0x10])	#PayloadLength = 0, unlimited 16 bytes
	spi.xfer2([0xB9,NODE])	#Node 10
	spi.xfer2([0xBA,0xD2])	#Broadcast 210
	spi.xfer2([0xBC,0x8F])	#FifoTresh, not empty, level 15
	spi.xfer2([0xBD,0x10])	#PacketConfig2, interpkt = 1, autorxrestart off
	spi.xfer2([0xCF,0x20])	#TestDagc ...

def get_idx() :					#Get domoticz object indexes, if they dont exists created the 5 objects in or case Energy meters
	inputfile = 'oemidx.txt'	#Assuming it is in the same directory as this script
	try :
		f = open(inputfile)
		idx = json.load(f)		#Read index values from file
	except IOError :			#File didn't exist. Create new one.
		f = open(inputfile, 'w')
		json.dump(IDX, f)		#Write domoticz indexes to file.
		idx=IDX
	f.close()
	return(idx)

def get_totals() :				#Get day totals after a reboot
	global totals
	inputfile = 'oemtotals.txt'
	try :
		f = open(inputfile)
		totals = json.load(f)	#Read index values from file
	except IOError :			#File didn't exist. Create new one.
		f = open(inputfile, 'w')
		totals=TOTALS
		json.dump(totals, f)	#Write domoticz indexes to file.
	f.close()
	return(totals)				#Return totals that where saved in file.
		
def handler (signum, frame) :	#Shutdown detected save totals
	global totals
	f = open('oemtotals.txt', 'w')
	json.dump(totals, f)		#Write totals to file so they dont get lost.
	f.close()
	sys.exit()					#Stop program for shutdown or reboot

def readfifo (channel) :		#Packet received, read FIFO.
	global lasttime
	global totals
	crc=7487					#crc=crc16_update(0xFFFF,GROUP). Start CRC calculation with GROUP byte
	data=spi.readbytes(17)[1:]	#Read Package, remove first byte
	for n in range(16) :		#Calculate CRC over al bytes
		crc=crc16_update(crc,data[n])	#[0xAA,0xAA,0xAA,0x2D]+. When I start at GROUP my CRC ends with 0.
	print data,crc						#Debugging
	if crc==0 :							#Payload is data integrity checked and OK
		#Calculate wattage and publisch the data to domoticz for all 4 CTs. CR is the voltage correction.Here in Canada we use 120V.
		watt[2] = (data[6]+(data[7]<<8))/CR		#Calculate wattage at this moment. data[2] is LSB and data[3] is MSB 
		watt[3] = (data[8]+(data[9]<<8))/CR
		watt[0] = ((data[2]+(data[3]<<8))/CR) #- watt[2] #Remove -watt[2] this is power used by my sub panel
		watt[1] = ((data[4]+(data[5]<<8))/CR) #- watt[3] #Remove -watt[3] this is power used by my sub panel
		watt[4] = watt[0]+watt[1]+watt[2]+watt[3]
		volt = float(data[10]+(data[11]<<8))/100#OEM Battery Voltage
		temp = float(data[12]+(data[13]<<8))/10	#OEM Temperature censor
		currenttime = time.time()	#How much time has passed since last measurement
		for n, wattage in enumerate(watt) :
			totals[n] += (currenttime-lasttime)*wattage  #Calculate wattage used between now and last measurement
			url= DOMOTICZ_URL+"/json.htm?type=command&param=udevice&idx="+idx[n]+"&nvalue=0&svalue="+str(wattage)+";"+str(totals[n]/3600) #Convert W/s to kWh
			requests.get(url)	
		lasttime=currenttime
		url= DOMOTICZ_URL+"/json.htm?type=command&param=udevice&idx="+IDX[5]+"&nvalue=0&svalue="+str(volt) #Send OEM Battery voltage to Domoticz
		requests.get(url)	
		url= DOMOTICZ_URL+"/json.htm?type=command&param=udevice&idx="+IDX[6]+"&nvalue=0&svalue="+str(temp) #Send OEM Temperature to Domoticz
		requests.get(url)	
	
#Main
spi = spidev.SpiDev()
#spi.open(0,0)							#Open SPI interface with CS0 (Chip Select 0) low
spi.open(0,1)							#Open SPI interface with CS1 (Chip Select 1) low
spi.bits_per_word=8 					#Using bytes for read and write.
spi.mode=0								#SPI mode.
spi.max_speed_hz=10000000				#SPI speed max 10 Mhz for RFM69.
signal.signal(signal.SIGTERM, handler)	#Detect system shutdown to save totals
init_RFM69()							#Set up our RFM69 for receiving
idx=get_idx()							#Get and if not exist create index values for energy meters
totals=get_totals()						#Get day totals from file.
GPIO.setmode(GPIO.BOARD)				#Using board numbers for IO.
GPIO.setup(22, GPIO.IN)					#Use pin 22 for DIO0. Interrupt when Payload Ready. Active High.
GPIO.add_event_detect(22, GPIO.RISING,callback=readfifo) #Package received.		
spi.writebytes(RFM69_RECEIVER)			#Let's play ball. Start Receiving. Look for sync signal
	
try:
	while True :
		time.sleep(3600)			#Sleep for a while. Software is interrupt driven.
except KeyboardInterrupt :			#Ctrl+C pressed, so...
	spi.close()						#Close hardware
	f = open('oemtotals.txt', 'w')  #Open file for saving totals
	json.dump(totals, f)			#Write totals to file for later use.
	f.close()
alexsh1
Posts: 169
Joined: Wednesday 30 September 2015 11:50
Target OS: Raspberry Pi / ODroid
Domoticz version: v3.8975
Location: United Kingdom
Contact:

Open Energy Monitor

Post by alexsh1 »

Apologies for bringing up this old thread.
This script is fully working on RPi2, right?
dwmw2
Posts: 52
Joined: Thursday 03 December 2015 12:42
Target OS: Linux
Domoticz version:
Contact:

Re: Open Energy Monitor

Post by dwmw2 »

I got an emonTx today too; I confess that for now I'm cheating and just reading data from the serial port:

Code: Select all

CT1 CT2 CT3 CT4 VRMS/BATT PULSE                                                 
1301 0 1204 64 23914 2                                                          
1322 0 1223 60 23886 5                                                          
1313 0 1221 58 23981 9                                                          
It should be possible to get rtl_433 receiving its data too; I've added some traces to the rtl_433_tests repository and will work on getting the decoding to work: https://github.com/merbanan/rtl_433_tests/pull/67

I haven't quite worked out what sensor types to use with Domoticz though. I can't see a sensor type which has only a power value in Watts; only one which also has a counter. And the although I do also have the pulse counter, the Domoticz sensor for that doesn't work correctly when the unit restarts and the pulse counter resets.
alexsh1
Posts: 169
Joined: Wednesday 30 September 2015 11:50
Target OS: Raspberry Pi / ODroid
Domoticz version: v3.8975
Location: United Kingdom
Contact:

Re: Open Energy Monitor

Post by alexsh1 »

dwmw2 wrote:
I haven't quite worked out what sensor types to use with Domoticz though. I can't see a sensor type which has only a power value in Watts; only one which also has a counter. And the although I do also have the pulse counter, the Domoticz sensor for that doesn't work correctly when the unit restarts and the pulse counter resets.
I have the total kwt counter working fine with arduino + pulse count + MySensors
Attachments
Screenshot (17).png
Screenshot (17).png (33.63 KiB) Viewed 8122 times
Post Reply

Who is online

Users browsing this forum: No registered users and 1 guest