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)
1 Like

Thank you so much for sharing this! I am in a similar situation and I think this script will help me.

Quick question: How do you consume this information within HomeAssistant? Does it show up as a standard power sensor you can add to the power dashboard? Or did you have to tell the MQTT integration to subscribe to the “rainforest” topic?
Thank you again!

Sorry for being late, I only hop on this form now and then.
Yes, I had to add this to my configuration:

mqtt:
  sensor:
    - state_topic: "rainforest/power"
      name: EMU-2 Power
      device_class: power
      unit_of_measurement: kW
      state_class: measurement
      unique_id: emu-2-power-32a656710cb2
    - state_topic: "rainforest/energy-delivered"
      name: EMU-2 Summation Delivered
      device_class: energy
      unit_of_measurement: kWh
      state_class: total_increasing
      unique_id: emu-2-summation-delivered-32a656710cb2
    - state_topic: "rainforest/energy-received"
      name: EMU-2 Summation Received
      device_class: energy
      unit_of_measurement: kWh
      state_class: total_increasing
      unique_id: emu-2-summation-received-32a656710cb2