EMU-2 to MQTT

  • I got the EMU-2, PSE’s official way to get live power data, a while ago. It has limited range since it communicates directly with the meter.
  • There’s a community integration that connects over serial. First, I tried plugging the EMU-2 into the HA host, but it was out of range. So, I begrudgingly set up a Pi closer, plugged it in, allowed for streaming serial access, and after a few hours got it to work.
  • At some point, that stopped working. I tried a few things, but it stayed broken.
  • So I disabled the serial hosting and wrote my own code. Now, I can just get the live power and cumulative power via MQTT. It seems more reliable and maybe even more real-time.
In the off-chance this helps anyone, here's the code that sends the live power to MQTT

print(“loading…”)
import paho.mqtt.client as mqtt
import serial
import time
import xml.etree.ElementTree as ETree

conn = serial.Serial(“/dev/ttyACM0”, 115200, timeout=1)
ha = mqtt.Client(“rainforest”)
ha.username_pw_set(“mqtt”, “M2vRaGmH”)
ha.connect(“homeassistant.local”)
print(“connecting…”)

ha.loop_start()
while True:
if conn.in_waiting > 0:
try:
data = conn.read(conn.in_waiting).decode(“utf-8”)
except:
print(“failed to decode”)
continue
try:
xml = ETree.fromstring(data)
except:
time.sleep(0.1)
data += conn.read(conn.in_waiting).decode()
try:
xml = ETree.fromstring(data)
except:
print(“failed to parse”, data)
continue
print(“parsed”, data)
if xml.tag == “InstantaneousDemand”:
demand = int(xml.find(“Demand”).text, 16)
multiplier = int(xml.find(“Multiplier”).text, 16)
divisor = int(xml.find(“Divisor”).text, 16)
digitsRight = int(xml.find(“DigitsRight”).text, 16)
if divisor != 0:
ha.publish(
“rainforest/power”,
str(round(demand * multiplier / divisor, digitsRight) * 40),
)
elif xml.tag == “CurrentSummationDelivered”:
delivered = int(xml.find(“SummationDelivered”).text, 16)
delivered *= int(xml.find(“Multiplier”).text, 16)
delivered /= int(xml.find(“Divisor”).text, 16)
ha.publish(“rainforest/energy-delivered”, str(delivered * 40))

        received = int(xml.find("SummationReceived").text, 16)
        received *= int(xml.find("Multiplier").text, 16)
        received /= int(xml.find("Divisor").text, 16)
        ha.publish("rainforest/energy-received", str(received * 40))

else:
    time.sleep(0.25)