Skip to content
Open
5 changes: 5 additions & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
serial
modbus_tk
configparser
pymodbus
paho-mqtt
11 changes: 9 additions & 2 deletions sdm630-mqtt.conf
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,15 @@ keepalive=10
topic_prefix=/sdm630

[sdm630]
host=localhost
port=5002
regfile=registers.csv
num_meters=1
id1=1
connection_type=tcp

[tcp]
host=localhost
port=5002

[rs485]
PORT=/dev/usbserial/sdm630
BAUDRATE=9600
24 changes: 17 additions & 7 deletions sdm630-mqtt.py
100644 → 100755
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#!/usr/bin/env python3
# -*- coding: utf_8 -*-

from sdm630 import SDM630
from sdm630 import *

import sys
import serial
Expand All @@ -28,7 +28,7 @@ def publish(topic,value):
config = ConfigParser.ConfigParser()
confread = config.read(CONFIG_FILE)
logging.info("Read config {}".format(confread))
logging.info("Opening port {}".format(config.get("sdm630","port")))


logging.info("Connecting to MQTT server...")
mqclient = mqtt.Client()
Expand All @@ -45,12 +45,22 @@ def publish(topic,value):
logging.info("Setup...")
num_meters = config.getint("sdm630","num_meters")
meters = []
connection_type = config.get("sdm630", "connection_type")

for i in range(num_meters):
meter = SDM630(config.get("sdm630","host"),
config.get("sdm630","port"),
config.getint("sdm630","id"+str(i+1)),
config.get("sdm630","regfile"))
meter.connect()
if connection_type == 'tcp':
logging.info("Opening port {}".format(config.get("tcp","port")))
meter = SDM630TCP(host=config.get("tcp","host"),
port=config.get("tcp","port"),
aid=config.getint("sdm630","id"+str(i+1)),
regfile=config.get("sdm630", "regfile"))
elif connection_type == 'rs485':
logging.info("Opening port {}".format(config.get("rs485","port")))
meter = SDM630RS485(config.get("rs485","PORT"),
config.getint("rs485","BAUDRATE"),
config.getint("sdm630","id"+str(i+1)),
regfile=config.get("sdm630", "regfile"))

meters.append(meter)

logging.info("Entering endless loop")
Expand Down
41 changes: 31 additions & 10 deletions sdm630.py
Original file line number Diff line number Diff line change
@@ -1,28 +1,25 @@
# -*- coding: utf_8 -*-

from pymodbus.client.sync import ModbusTcpClient
from pymodbus.client.sync import ModbusSerialClient
from pymodbus.payload import BinaryPayloadDecoder
from pymodbus.constants import Endian

import serial
import time
import csv

class SDM630(object):
def __init__(self,host,port,aid,regfile):
def __init__(self, regfile):
self.__fill_registers__(regfile)

def __fill_registers__(self, regfile):
self.registers = {}
with open(regfile) as regs:
reader = csv.reader(regs,delimiter=';')
for line in reader:
self.registers[line[1]] = int(line[0],base=16)
self.aid = aid
self.host = host
self.port = port

def connect(self):
self.master = ModbusTcpClient(host=self.host,port=self.port)
# self.master.set_timeout(1.0)
# self.master.set_verbose(True)



def __getattr__(self,attr):
if attr == "voltx3":
Expand All @@ -46,3 +43,27 @@ def read_registers(self,addr,count):
return decoder.decode_32bit_float()
return tuple(decoder.decode_32bit_float() for _ in range(count))

# connecting using tcp
class SDM630TCP(SDM630):
def __init__(self,host,port,aid,regfile):
SDM630.__init__(self,regfile)

self.aid = aid
self.host = host
self.port = port

self.master = ModbusTcpClient(host=self.host,port=self.port)


# connecting using serial port
class SDM630RS485(SDM630):
def __init__(self, port, baudrate, aid, regfile):
SDM630.__init__(self,regfile)

self.port = port
self.baudrate = baudrate
self.aid = aid

self.master = ModbusSerialClient("rtu", port=self.port, baudrate=self.baudrate, timeout=1)


20 changes: 18 additions & 2 deletions test.py
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,11 @@

from struct import *
import serial
import sys
import modbus_tk
import modbus_tk.defines as cst
from modbus_tk import modbus_rtu
import configparser

def read_float(arrRegs):
reg1 = arrRegs[1]
Expand All @@ -32,17 +34,31 @@ def bcdDigits(chars):
return
yield val

PORT = '/dev/usbserial/sdm630'
SLAVE = 1

def main():
"""main"""
logger = modbus_tk.utils.create_logger("console")

CONFIG_FILE = 'sdm630-mqtt.conf'
if ((len(sys.argv) == 3) and sys.argv[1] == '-c'):
CONFIG_FILE = sys.argv[2]

config = configparser.ConfigParser()
config.read(CONFIG_FILE)
rs485 = config['rs485']
PORT=rs485.get('PORT')
BAUDRATE=rs485.getint('BAUDRATE', 9600)
BYTESIZE=rs485.getint('BYTESIZE', 8)
PARITY=rs485.get('PARITY', 'N')
STOPBITS=rs485.getint('STOPBITS', 1)
XONXOFF=rs485.getint('XONXOFF', 0)
DSRDTR=rs485.getboolean('DSRDTR', True)

try:
#Connect to the slave
master = modbus_rtu.RtuMaster(
serial.Serial(port=PORT, baudrate=9600, bytesize=8, parity='N', stopbits=1, xonxoff=0, dsrdtr=True)
serial.Serial(port=PORT, baudrate=BAUDRATE, bytesize=BYTESIZE, parity=PARITY, stopbits=STOPBITS, xonxoff=XONXOFF, dsrdtr=DSRDTR)
)
master.set_timeout(1.0)
# master.set_verbose(True)
Expand Down