Created
June 12, 2019 20:14
-
-
Save rufik/e40e91b5ddadfef9b284ca92f5e2bb1b to your computer and use it in GitHub Desktop.
Python script to read SDM630 power meter and publish to mqtt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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