Skip to content

Instantly share code, notes, and snippets.

@rufik
Created June 12, 2019 20:14
Show Gist options
  • Save rufik/e40e91b5ddadfef9b284ca92f5e2bb1b to your computer and use it in GitHub Desktop.
Save rufik/e40e91b5ddadfef9b284ca92f5e2bb1b to your computer and use it in GitHub Desktop.
Python script to read SDM630 power meter and publish to mqtt
#!/usr/bin/python
import minimalmodbus
import paho.mqtt.client as mqtt
import paho.mqtt.publish as pub
# RS485 serial settings
DEVICE="/dev/ttyUSB0"
SLAVE=2
DEBUG=False
FUNCODE=4
REG_NO=2
# MQTT settings
MQTT_HOST="localhost"
MQTT_PORT=1883
MQTT_TOPIC="power/sdm630/{}/".format(SLAVE)
REGISTERS = {
"L1_Voltage": 0,
"L2_Voltage": 2,
"L3_Voltage": 4,
"L1_Current": 6,
"L2_Current": 8,
"L3_Current": 10,
"L1_L2_Voltage": 200,
"L2_L3_Voltage": 202,
"L3_L1_Voltage": 204,
"L1_Active_Power": 12,
"L2_Active_Power": 14,
"L3_Active_Power": 16,
"L1_Apparent_Power": 18,
"L2_Apparent_Power": 20,
"L3_Apparent_Power": 22,
"L1_Reactive_Power": 24,
"L2_Reactive_Power": 26,
"L3_Reactive_Power": 28,
"L1_Power_Factor": 30,
"L2_Power_Factor": 32,
"L3_Power_Factor": 34,
"L1_Phase_Angle": 36,
"L2_Phase_Angle": 38,
"L3_Phase_Angle": 40,
"L1_Current_THD": 240,
"L2_Current_THD": 242,
"L3_Current_THD": 244,
"Total_System_Power": 52,
"Total_System_VA": 56,
"Total_System_VAR": 60,
"Total_System_Power_Demand": 84,
"Total_System_Power_Demand_Max": 86,
"Total_System_VA_Demand": 100,
"Frequency": 70,
"Import_Active_Energy": 72,
"Export_Active_Energy": 74,
"Import_Reactive_Energy": 76,
"Export_Reactive_Energy": 78,
"Total_Active_Energy": 342,
"Total_Reactive_Energy": 344,
}
def setup_serial():
# serial port setup
rs485 = minimalmodbus.Instrument(DEVICE, SLAVE)
rs485.serial.baudrate = 9600
rs485.serial.bytesize = 8
rs485.serial.parity = minimalmodbus.serial.PARITY_NONE
rs485.serial.stopbits = 1
rs485.serial.timeout = 1
rs485.mode = minimalmodbus.MODE_RTU
rs485.debug = False
if DEBUG:
print("Serial port settings: {}".format(rs485))
return rs485
def read_register(serial, reg):
value = serial.read_float(reg, FUNCODE, REG_NO)
if DEBUG:
print("Register Value read is: {}".format(value))
return value
def publish_values(values):
for reg_name, reg_val in values.items():
if DEBUG:
print("Publising register {}={} to MQTT".format(reg_name, reg_val))
pub.single(MQTT_TOPIC + reg_name, "{0:.1f}".format(reg_val), qos=2, hostname=MQTT_HOST, port=MQTT_PORT, client_id="sdm630_mqtt")
# main logic
print("Start")
values = {}
rs845 = setup_serial()
print("Reading of SDM630 registers started...")
for reg_name, reg_no in REGISTERS.items():
if DEBUG:
print("Dealing with register: {} [register={}]".format(reg_name, reg_no))
reg_val = read_register(rs845, reg_no)
values[reg_name] = reg_val
print("Reading of SDM630 registers finished, {} items.".format(len(values)))
print("Publising values to MQTT...")
publish_values(values);
print("End")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment