The short answer is, that I didn’t get either one to work with the included bindings. So I am using python scripts which post to the REST API. They work very well. Here are my both scripts:
# -*- coding: ISO-8859-1 -*-
import serial
import time
import faulthandler, signal, os, traceback
from datetime import datetime
import re
from urllib import request, parse
import multiprocessing
SERIALPORT = "/dev/serial/by-id/usb-FTDI_FT232R_USB_UART_AH0694UP-if00-port0"
INITAL_BAUDRATE = 300
def postUdpate(item, value):
req = request.Request("http://localhost:8080/rest/items/"+item+"/state", data=str(value).encode('utf-8'))
req.add_header('Content-Type', 'text/plain')
req.get_method = lambda: 'PUT'
resp = request.urlopen(req)
if resp.status!=202 :
print("Response was %s %s" % (resp.status, resp.reason))
def startQuery():
ser.baudrate = INITAL_BAUDRATE
if (ser.in_waiting != 0): #ensure we are not reading garbage and the buffer is empty
ser.read(ser.in_waiting)
time.sleep(0.3)
sendtxta = "/?!\r\n"
ser.write(sendtxta.encode())
ser.flush()
response=ser.readline()
#print(response) #this is the echo
response=ser.readline()
#print(response)
sendtxta = "\x06040\r\n"
ser.write(sendtxta.encode())
ser.flush()
time.sleep(0.3)
ser.baudrate = 4800
#print("Switching to {}".format(ser.baudrate))
def usr1_handler(signum,frame):
traceback.print_stack()
def startQueryLoop():
signal.signal(signal.SIGUSR1,usr1_handler)
startQuery()
while True:
response=ser.readline()
#print(response)
regexMatch = re.search('1.8.0\((.*)\*kWh\).*', response.decode("UTF-8"))
if regexMatch:
power = regexMatch.group(1)
print(".", end='', flush=True)
postUdpate("energyHeatpumpTotal", power)
if (response==b'!\r\n'):
#print("Switching to {}".format(INITAL_BAUDRATE))
ser.baudrate = INITAL_BAUDRATE
time.sleep(0.3)
return None
def usr1_handler(signum,frame):
traceback.print_stack()
def usr1_handler_main(signum, frame):
os.kill(p.pid, signal.SIGUSR1)
signal.signal(signal.SIGUSR1,usr1_handler_main)
ser = serial.Serial(SERIALPORT, INITAL_BAUDRATE, serial.SEVENBITS, serial.PARITY_EVEN,serial.STOPBITS_ONE)
p=None
while True:
p = multiprocessing.Process(target=startQueryLoop)
p.start()
# Wait for 10 seconds or until process finishes
p.join(10)
# If thread is still active
if p.is_alive():
print("\n{} Timeout, restart of process".format(datetime.now().strftime('%Y-%m-%d %H:%M:%S')))
# Terminate
p.terminate()
p.join()
This is for the Logarex:
# -*- coding: ISO-8859-1 -*-
import serial
import time
import faulthandler, signal, os, traceback
from datetime import datetime
import re
from urllib import request, parse
import multiprocessing
SERIALPORT = "/dev/serial/by-id/usb-FTDI_FT232R_USB_UART_AH0694V2-if00-port0"
INITAL_BAUDRATE = 9600
def postUdpate(item, value):
req = request.Request("http://localhost:8080/rest/items/"+item+"/state", data=str(value).encode('utf-8'))
req.add_header('Content-Type', 'text/plain')
req.get_method = lambda: 'PUT'
resp = request.urlopen(req)
if resp.status!=202 :
print("Response was %s %s" % (resp.status, resp.reason))
def usr1_handler(signum,frame):
traceback.print_stack()
def startQueryLoop():
signal.signal(signal.SIGUSR1,usr1_handler)
while True:
try:
response=ser.readline()
#print(response.decode("UTF-8"))
regexMatch = re.search('1-0:1.8.0\*255\((.*)\*kWh\).*', response.decode("UTF-8"))
if regexMatch:
power = regexMatch.group(1)
#print("Power: {}".format(float(power)))
print(".", end='', flush=True)
postUdpate("energyHouseholdTotal", power)
except Exception as e:
print("An exception occurred")
time.sleep(10)
ser = serial.Serial(SERIALPORT, INITAL_BAUDRATE, serial.SEVENBITS, serial.PARITY_EVEN,serial.STOPBITS_ONE)
startQueryLoop()
With those items
Group gEnergy "Energy"
Number:Energy energyHouseholdTotal "Haushaltsstrom Gesamt [%.4f kWh]" <consumption> (gEnergy)
Number:Energy energyHeatpumpTotal "Wärmestrom Gesamt [%.4f kWh]" <consumption> (gEnergy)
The killing and respawning of a process is quite compute intensive. But I noticed that the EMH occasionally crashes! And as the serial port API does not appear to have a timeout, I am using processes… Not good, but at least it works.