If entry to Domoticz through the frontdoor is not possible for unclear reasons, you look for entry through the backdoor .....
Which means that I searched & found a Python-script for upload of data, sufficiently compatible with my read-out script for the RS485-interface of the DDS238-1ZN kWh-meter.
The resulting script is shown below.
Application requires installation of the Python-modules serial and minimalmodbus, as required to deal with RS485-interface & Modbus.
The debug mode of minimalmodbus is a bonus when tuning & testing your application of this script: see line 34 of the script for it's (de)activation.
If you have Domoticz running, all other modules are present for import.
The different origins of the 2 parts of this basic script can be well recognized, not only by the separation bars I have inserted, but also by the structure.
Part 1 is the read-out of
all registers of the DDS238's RS485-interface. Part 2 is dedicated to upload to PVOutput for v1, v2, v6 and c1.
At the start of the 2nd part (for Upload) I have simply imported there the modules extra needed in part 2, and have linked there the settings and parameters of part 2 to those in part 1, instead of only one section for the whole script for import & definition.
The script looks long, but for 'easy visibility' especially in Part1 I have programmed in small steps, and inserted plenty of print-lines/comments
1) to satisfy my curiosity to the operation of the DDS238-interface and 2) to ease error-trapping.
If you take out all print-lines and comments as well as all lines
not related to LIFENERGY, POWER and VOLTAGE, the file considerably shrinks, and a skilled programmer may surely further combine various lines towards an even leaner script.
Periodical unattended running of the script requires a cronjob.
Obviously, suggestions for improvement are welcome:
- first candidate seems a form of correction for a missing read-out by repeating reading-cycles until success
[because not all read-requests are immediately successful].
- second candidate (for PV-application) is suppression of increase of 'life-energy' being reported before sunrise and after sunset
[Cannot be caused by PV-production. Due to spurious measurements, or a side-effect of standby-consumption? In that perspective the addition of the indicated calculation for 'true' Wh-today may have merits combined with a time-window for 'legal' uploads].
This script is for a DDS238-1ZN kWh-meter with it's AC-wiring set to give positive values for Forward Energy & Power for PV-production at the RS485-interface and S0-interface.
Reverse energy then implies 'consumption', and Life net energy = (Forward Energy) - (Reverse Energy)
Not documented, nor critical for the PV-production assumed in this script (0<P<32768 VA), but negative/reverse Power is represented by a value >32768.
Apparently for negative/reverse Power you need to apply 2-complement. For calculation of negative Power a simple placeholder inserted in this script by
if ActivPower > 65535/2:
ActivPower = ActivPower - 65534
The above aspects are valid for DDS238-1ZN: for another kWh-meter with RS485-interface, you will see other peculiar aspects, starting with other register-addresses and other functions.
This script is a practical solution to get the data in the 'System', but for control applications the direct entry within this script to Domoticz through the frontdoor is better: for that aspect see my later message
http://www.domoticz.com/forum/viewtopic ... 227#p72227
Code: Select all
#!/usr/bin/python
# -*- coding = utf-8 to enable reading by simple editors -*-
# --------------------------------------------------
# Line004 = PREPARATION & SETTINGs
# --------------------------------------------------
# For script-operation
import serial # required for handling of the serial port
import minimalmodbus # required for handling modbus
import datetime # used for timestamp
# Line013 = Provide here the settings for access to PVOutput
slave = 1 # decimal slave-address of the DDS238 kWh-meter
pvout_enabled = True
pvout_apikey = "<YOUR API-key string for PVOutput>"
pvout_sysid = <YOUR SID for PVOutput>
pvout_cumflag = 1 # flag is 1 if you apply lifetime-energy as reported by DDS238
# flag must be 0 if you upload a calculated Wh_today
# --------------------------------------------------
# Line023 = READING THE RS485-INTERFACE OF DDS238
# --------------------------------------------------
# the "print"-lines only added for local read-out e.g. during script_tuning
now = datetime.datetime.now()
print
print 'Time = ', now
print
instrument = minimalmodbus.Instrument('/dev/ttyAMA0',slave) # port name, slave address
instrument.serial.baudrate = 9600
instrument.serial.timeout = 0.5
# instrument.debug = True
print instrument
print
print '== Read-out as integer-lists from 4 bytes =='
print 'Registers 01/00 = Life_Net_Energy'
print instrument.read_registers(0,2) # startregister, number of registers
print 'Registers 09/08 = Reverse_Energy'
print instrument.read_registers(8,2) # startregister, number of registers
print 'Registers 11/10 = Forward_Energy'
print instrument.read_registers(10,2) # startregister, number of registers
print
print '== Read-out as integers from 2 bytes =='
x=12
while x<22:
print 'Register ', x
print instrument.read_register(x,0) # register, number of decimals
x = x + 1
print
#print '== Values after scalecorrection & check =='
TotalEnergy1 = instrument.read_registers(0,2)
LifeEnergy_High = TotalEnergy1[0]
LifeEnergy_Low = TotalEnergy1[1]
LifeEnergy = 0.01 * ((LifeEnergy_High * 65535) + LifeEnergy_Low)
#print 'Life_Net_Energy = ', LifeEnergy, ' kWh'
LIFENERGY = LifeEnergy * 1000
TotalEnergy2 = instrument.read_registers(8,2)
RevEnergy_High = TotalEnergy2[0]
RevEnergy_Low = TotalEnergy2[1]
RevEnergy = 0.01 * ((RevEnergy_High * 65535) + RevEnergy_Low)
#print 'Reverse_Energy = ', RevEnergy, ' kWh'
REVENERGY = RevEnergy * 1000
TotalEnergy3 = instrument.read_registers(10,2)
FwdEnergy_High = TotalEnergy3[0]
FwdEnergy_Low = TotalEnergy3[1]
FwdEnergy = 0.01 * ((FwdEnergy_High * 65535) + FwdEnergy_Low)
#print 'Forward_Energy = ', FwdEnergy, ' kWh'
FWDENERGY = FwdEnergy * 1000
Voltage = instrument.read_register(12,1)
#print 'Voltage = ', Voltage, ' V'
VOLTAGE = Voltage
Current = instrument.read_register(13,2)
#print 'Current = ', Current, ' A'
CURRENT = Current
ActivPower = instrument.read_register(14,0)
#print 'Activpower-register = ', ActivPower
if ActivPower < 65535/2:
# print '=> ActivePower = ', ActivPower, ' VA'
PRODUCTION = ActivPower
CONSUMPTION = 0
else:
ActivPower = ActivPower - 65534
# print '=> ActivePower = ', ActivPower, ' VA'
PRODUCTION = 0
CONSUMPTION = - ActivPower
POWER = PRODUCTION
ReactPower = instrument.read_register(15,0)
#print 'ReactivePower = ', ReactPower, ' VAR'
PF = instrument.read_register(16,3)
#print 'PowerFactor = ', PF
Freq = instrument.read_register(17,2)
#print 'Frequency = ', Freq, ' Hz'
Status = instrument.read_register(21,0)
Adres = Status/256
print 'DDS238_Status, Address = ', Adres
Rate = Status%256
print 'DDS238_Status, Baudrate = ', Rate
print
# errortrapping to be added, because not every call to a register is successful .......
# --------------------------------------------------
# END READING RS485-INTERFACE OF DDS238
# --------------------------------------------------
# --------------------------------------------------
# START OF UPLOAD TO PVOUTPUT
# --------------------------------------------------
# For script-operation
import subprocess
from time import strftime
import time
# Presetting of parameters
SYSTEMID = pvout_sysid
APIKEY = pvout_apikey
t_date = format(strftime('%Y%m%d'))
t_time = format(strftime('%H:%M'))
pv_volts=0.0
pv_power=0.0
Wh_life=LIFENERGY
Wh_today=0
# space for addition of a calculation for current_temp
if pvout_enabled and (POWER >=0):
pv_volts=VOLTAGE
pv_power=POWER
Wh_life=LIFENERGY
cum=pvout_cumflag
cmd=('curl -d "d=%s" -d "t=%s" -d "v1=%s" -d "v2=%s" -d "v6=%s" -d "c1=%s" -H \
"X-Pvoutput-Apikey: %s" -H \
"X-Pvoutput-SystemId: %s" \
http://pvoutput.org/service/r2/addstatus.jsp'\
%(t_date, t_time, Wh_life, pv_power, pv_volts, cum, \
APIKEY, SYSTEMID))
ret = subprocess.call(cmd, shell=True)
# space for addition of a calculation for Wh_today
#time.sleep(20) # delay until next lines
#if Wh_today>0: # if you apply a calculated Wh_today
# cmd=('curl -d "data=%s,%s,,,,,,," -H \
# "X-Pvoutput-Apikey: %s" -H \
# "X-Pvoutput-SystemId: %s" http://pvoutput.org/service/r2/addoutput.jsp' \
# %(t_date, Wh_today,\
# APIKEY,SYSTEMID))
# ret = subprocess.call(cmd, shell=True)
# --------------------------------------------------
# END OF UPLOAD TO PVOUTPUT
# --------------------------------------------------
print
print
print '= RS485-Values for Upload ='
print 'Life_Net_Energy = ', LIFENERGY, ' Wh'
print 'Forward_Rnergy = ', FWDENERGY, ' Wh'
print 'Reverse_Energy = ', REVENERGY, ' Wh'
print 'Voltage = ', VOLTAGE, ' V'
print 'Current = ', CURRENT, ' A'
print 'ActivePower = ', ActivPower, ' VA'
print '=> Production = ', POWER, ' VA'
print '=> Consumption = ', CONSUMPTION, ' VA'
print
print '= Uploaded to PVOutput ='
print 't_date %s' %t_date
print 't_time %s' %t_time
print 'pv_volts %s' %pv_volts
print 'pv_power %s' %pv_power
print 'Wh_life %s' %Wh_life