Step 1: Connect the A & B of energy meter to A & B pin in RuggedBoard RS485 port respectively.
For demonstration purpose I have used Elmeasure LG+ 1119 meter. If you are having any other meter then you have to read the datasheet of the meter vendor and provide proper parameters.
Step 2: Download the modpoll ARM execulatble binary and save it into your work directory. To download the file click below.
Step 3: Save the following code in .sh format on your working directory and name is as mbpoll.sh
./modpoll.bin -m rtu -a 1 -t 4:float -r 159 -b 9600 -s 1 -P none /dev/ttyS2
The above script has the following components:
m : communication mode
a : Slave address
t : data types of the slave holding register
r : Start Reference
b : Baudrate
s : Stopbits
p : Parity Bit
SERIALPORT : Serial port node of the RS485
Step 4: Run the above code to test ModBus communication
sh mbpoll.sh
Step 1: Connect the energy meter and the board as shown in the Stage 1.
Step 2: write the following code and save it as read_energymeter.py
#Python code to read data from Energy Meter:​from pymodbus.client.sync import ModbusSerialClient as ModbusClientfrom pymodbus.payload import BinaryPayloadDecoderfrom pymodbus.payload import BinaryPayloadBuilderfrom pymodbus.constants import Endianimport time​client = ModbusClient(method='rtu', port='/dev/ttyS2', stopbits=1, bytesize=8, baudrate=9600, parity='N')​connection = client.connect()​counter = 1​while True:​print("==========================================================")print("Iteration {}" .format(counter))print("----------------------------------------------------------")​WattHour = client.read_holding_registers(0x009E, 2, unit=1)decoder = BinaryPayloadDecoder.fromRegisters(WattHour.registers, Endian.Big, wordorder=Endian.Little)​print("Watt Hour Reading:", float(decoder.decode_32bit_float()))​counter += 1​print("==========================================================")​time.sleep(2)​​
Step 3: Run the above code to read data from Energy Meter
python read_energymeter.py
I this stage you will be able to send command from cloud server (AWS) and start replying to the request from cloud. In this example we will send a command from cloud to start sending Energy Meter data and stop sending when the timer is out.
Step 1: Connect the energy meter and the board as shown in the Stage 1.
Step 2: Write the following code and save it as lg1119.py
#-------------------AWS MQTT init----------------------import paho.mqtt.client as pahoimport ssl, randomfrom time import sleepimport osimport jsonimport threading​#-----------------MODBUS init---------------------------from pymodbus.client.sync import ModbusSerialClient as ModbusClientfrom pymodbus.payload import BinaryPayloadDecoderfrom pymodbus.payload import BinaryPayloadBuilderfrom pymodbus.constants import Endian​#----------------Modbus client connection-------------------modclient = ModbusClient(method='rtu', port='/dev/ttymxc5', stopbits=1, bytesize=8, baudrate=9600, parity='N')connection = modclient.connect()​​#----------------Global Variables----------------------------Message = ''TIMER = 0Wflag = 0​mqtt_url = "a3hf64x6hul7tx-ats.iot.us-west-2.amazonaws.com"root_ca = '/home/root/certs/Amazon_Root_CA_1.pem'public_crt = '/home/root/certs/c17983007e-certificate.pem.crt'private_key = '/home/root/certs/c17983007e-private.pem.key'​​#----------------Functions-----------------------------------def ledOn():os.system("echo 29 > /sys/class/gpio/export")os.system("echo out > /sys/class/gpio/PA29/direction")os.system("echo 1 > /sys/class/gpio/PA29/value")os.system("echo 29 > /sys/class/gpio/unexport")​​def ledOff():os.system("echo 29 > /sys/class/gpio/export")os.system("echo out > /sys/class/gpio/PA29/direction")os.system("echo 0 > /sys/class/gpio/PA29/value")os.system("echo 29 > /sys/class/gpio/unexport")​def publishOn():client.publish("Aws_regor", '{"voltage":' + str(Volt_val) + ', "frequency":' + str(Freq_val) + ', "status": "ON", "kwh":' + str(kWh_val) + ', "cost":' + str(cost) + '}', qos = 1)​def publishOff():client.publish('Aws_regor', '{"voltage":' + str(Volt_val) + ', "frequency":' + str(Freq_val) + ', "status": "OFF", "kwh":' + str(kWh_val) + ', "cost":' + str(cost) + '}', qos = 1)​def timerCb():global Messageglobal TIMERglobal Wflagprint("Timer elapsed\n\nTurning off")#ledOff()publishOff()#client.publish('Aws_regor', '{"voltage":' +str(Volt_val)', "frequency":' +str(Freq_val)', "message": "OFF"}', qos = 1)Message = ''TIMER = 0Wflag = 0​def on_connect(client, userdata, flags, rc):print("Connected with result code " + str(rc))client.subscribe("ExampleTopic")print("Subscribed")​​def on_message(client, userdata, msg):global Messageglobal TIMERglobal timerglobal Wflagprint ("Message Received")print (msg.payload.decode("utf-8"))msg.payload=msg.payload.decode("utf-8")recvMesg = msg.payloadjsonMesg = json.loads(recvMesg)Message = jsonMesg['message']if (Message == 'ON'):TIMER = jsonMesg['timer']timer = threading.Timer(TIMER * 60, timerCb)#ledOn()timer.start()Wflag = 1print("Turning on LED")#client.publish("sdk/test/cpp", 'ON', qos=1)​elif (Message == 'OFF'):#ledOff()print ("Turning off LED")timer.cancel()publishOff()Wflag = 0#client.publish("sdk/test/cpp", 'OFF', qos=1)​client = paho.Client()client.tls_set(root_ca,certfile = public_crt,keyfile = private_key,cert_reqs = ssl.CERT_REQUIRED,tls_version = ssl.PROTOCOL_TLSv1_2,ciphers = None)​​client.on_connect = on_connectclient.on_message = on_message​client.connect(mqtt_url, port = 8883, keepalive=60)client.loop_start()​# Publish to the same topic in a loop foreverloopCount = 0​while True:​if (Message == 'ON'):​'''LineToNeutral = modclient.read_holding_registers(0x0F46, 2, unit=1)decoder = BinaryPayloadDecoder.fromRegisters(LineToNeutral.registers, Endian.Big, wordorder=Endian.Little)Volt_val = float(decoder.decode_32bit_float())print("Line To Neutral Voltage:", Volt_val)Frequency = modclient.read_holding_registers(0x0F4A, 2, unit=1)decoder = BinaryPayloadDecoder.fromRegisters(Frequency.registers, Endian.Big, wordorder=Endian.Little)Freq_val = float(decoder.decode_32bit_float())print("Frequency:", Freq_val)'''Freq_val = 49.906Volt_val = 230.507Watthour = modclient.read_holding_registers(0x009E, 2, unit=1)decoder = BinaryPayloadDecoder.fromRegisters(Watthour.registers, Endian.Big, wordorder=Endian.Little)Wh_val = float(decoder.decode_32bit_float())kWh_val = Wh_val / 1000.0print("kWh: ", kWh_val)​if Wflag == 1:WhIn = Wh_valWflag = 0​print(WhIn, Wh_val, (Wh_val - WhIn))cost = (Wh_val - WhIn) * 0.2print("==========================================================")#volt_val = str(LineToNeutral.registers)#freq_val = str(Frequency.registers)​publishOn()sleep(5)​​elif (Message == 'OFF'):Wflag = 0​sleep(250/10000000.0)​
Step 3: Run the above code to read data from Energy Meter
python lg1119.py
Step 4: Visit the following website and check the live energy meter data
​https://ruggedboard.com/ev_demo/mqttSample/index.html​