Smart Energy Meter with AWS cloud
Vertical: Industry 4.0

Stage 1 : Testing ModDus Communication (RS485) using modpoll

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.
modpoll.bin
644KB
Binary
modpoll.bin
Step 3: Save the following code in .sh format on your working directory and name is as mbpoll.sh
1
./modpoll.bin -m rtu -a 1 -t 4:float -r 159 -b 9600 -s 1 -p none /dev/ttyS2
Copied!
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

If everything is correct your code will run without any error. and you can proceed to next stage.

Stage 2: Reading the Energy Meter values using Python 3 Script.

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
1
#Python code to read data from Energy Meter:
2
3
from pymodbus.client.sync import ModbusSerialClient as ModbusClient
4
from pymodbus.payload import BinaryPayloadDecoder
5
from pymodbus.payload import BinaryPayloadBuilder
6
from pymodbus.constants import Endian
7
import time
8
9
client = ModbusClient(method='rtu', port='/dev/ttyS2', stopbits=1, bytesize=8, baudrate=9600, parity='N')
10
11
connection = client.connect()
12
13
counter = 1
14
15
while True:
16
17
print("==========================================================")
18
print("Iteration {}" .format(counter))
19
print("----------------------------------------------------------")
20
21
WattHour = client.read_holding_registers(0x009E, 2, unit=1)
22
decoder = BinaryPayloadDecoder.fromRegisters(WattHour.registers, Endian.Big, wordorder=Endian.Little)
23
24
print("Watt Hour Reading:", float(decoder.decode_32bit_float()))
25
26
counter += 1
27
28
print("==========================================================")
29
30
time.sleep(2)
31
32
Copied!
Step 3: Run the above code to read data from Energy Meter
python read_energymeter.py

If everything is correct your code will run without any error and you can proceed to next stage to send the data to a AWS cloud and view it on a dashboard.

Stage 3: Reading the Energy meter values using Python 3 Script

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
1
#-------------------AWS MQTT init----------------------
2
import paho.mqtt.client as paho
3
import ssl, random
4
from time import sleep
5
import os
6
import json
7
import threading
8
9
#-----------------MODBUS init---------------------------
10
from pymodbus.client.sync import ModbusSerialClient as ModbusClient
11
from pymodbus.payload import BinaryPayloadDecoder
12
from pymodbus.payload import BinaryPayloadBuilder
13
from pymodbus.constants import Endian
14
15
16
#----------------Modbus client connection-------------------
17
modclient = ModbusClient(method='rtu', port='/dev/ttymxc5', stopbits=1, bytesize=8, baudrate=9600, parity='N')
18
connection = modclient.connect()
19
20
21
#----------------Global Variables----------------------------
22
Message = ''
23
TIMER = 0
24
Wflag = 0
25
26
mqtt_url = "a3hf64x6hul7tx-ats.iot.us-west-2.amazonaws.com"
27
root_ca = '/home/root/certs/Amazon_Root_CA_1.pem'
28
public_crt = '/home/root/certs/c17983007e-certificate.pem.crt'
29
private_key = '/home/root/certs/c17983007e-private.pem.key'
30
31
32
#----------------Functions-----------------------------------
33
def ledOn():
34
os.system("echo 29 > /sys/class/gpio/export")
35
os.system("echo out > /sys/class/gpio/PA29/direction")
36
os.system("echo 1 > /sys/class/gpio/PA29/value")
37
os.system("echo 29 > /sys/class/gpio/unexport")
38
39
40
def ledOff():
41
os.system("echo 29 > /sys/class/gpio/export")
42
os.system("echo out > /sys/class/gpio/PA29/direction")
43
os.system("echo 0 > /sys/class/gpio/PA29/value")
44
os.system("echo 29 > /sys/class/gpio/unexport")
45
46
def publishOn():
47
client.publish("Aws_regor", '{"voltage":' + str(Volt_val) + ', "frequency":' + str(Freq_val) + ', "status": "ON", "kwh":' + str(kWh_val) + ', "cost":' + str(cost) + '}', qos = 1)
48
49
def publishOff():
50
client.publish('Aws_regor', '{"voltage":' + str(Volt_val) + ', "frequency":' + str(Freq_val) + ', "status": "OFF", "kwh":' + str(kWh_val) + ', "cost":' + str(cost) + '}', qos = 1)
51
52
53
def timerCb():
54
global Message
55
global TIMER
56
global Wflag
57
print("Timer elapsed\n\nTurning off")
58
#ledOff()
59
publishOff()
60
#client.publish('Aws_regor', '{"voltage":' +str(Volt_val)', "frequency":' +str(Freq_val)', "message": "OFF"}', qos = 1)
61
Message = ''
62
TIMER = 0
63
Wflag = 0
64
65
66
def on_connect(client, userdata, flags, rc):
67
print("Connected with result code " + str(rc))
68
client.subscribe("ExampleTopic")
69
print("Subscribed")
70
71
72
def on_message(client, userdata, msg):
73
global Message
74
global TIMER
75
global timer
76
global Wflag
77
print ("Message Received")
78
print (msg.payload.decode("utf-8"))
79
msg.payload=msg.payload.decode("utf-8")
80
recvMesg = msg.payload
81
jsonMesg = json.loads(recvMesg)
82
Message = jsonMesg['message']
83
if (Message == 'ON'):
84
TIMER = jsonMesg['timer']
85
timer = threading.Timer(TIMER * 60, timerCb)
86
#ledOn()
87
timer.start()
88
Wflag = 1
89
print("Turning on LED")
90
#client.publish("sdk/test/cpp", 'ON', qos=1)
91
92
elif (Message == 'OFF'):
93
#ledOff()
94
print ("Turning off LED")
95
timer.cancel()
96
publishOff()
97
Wflag = 0
98
#client.publish("sdk/test/cpp", 'OFF', qos=1)
99
100
client = paho.Client()
101
client.tls_set(root_ca,
102
certfile = public_crt,
103
keyfile = private_key,
104
cert_reqs = ssl.CERT_REQUIRED,
105
tls_version = ssl.PROTOCOL_TLSv1_2,
106
ciphers = None)
107
108
109
client.on_connect = on_connect
110
client.on_message = on_message
111
112
client.connect(mqtt_url, port = 8883, keepalive=60)
113
client.loop_start()
114
115
# Publish to the same topic in a loop forever
116
loopCount = 0
117
118
while True:
119
120
if (Message == 'ON'):
121
122
'''
123
124
LineToNeutral = modclient.read_holding_registers(0x0F46, 2, unit=1)
125
decoder = BinaryPayloadDecoder.fromRegisters(LineToNeutral.registers, Endian.Big, wordorder=Endian.Little)
126
127
Volt_val = float(decoder.decode_32bit_float())
128
print("Line To Neutral Voltage:", Volt_val)
129
130
Frequency = modclient.read_holding_registers(0x0F4A, 2, unit=1)
131
decoder = BinaryPayloadDecoder.fromRegisters(Frequency.registers, Endian.Big, wordorder=Endian.Little)
132
133
Freq_val = float(decoder.decode_32bit_float())
134
print("Frequency:", Freq_val)
135
'''
136
Freq_val = 49.906
137
Volt_val = 230.507
138
139
Watthour = modclient.read_holding_registers(0x009E, 2, unit=1)
140
decoder = BinaryPayloadDecoder.fromRegisters(Watthour.registers, Endian.Big, wordorder=Endian.Little)
141
142
Wh_val = float(decoder.decode_32bit_float())
143
kWh_val = Wh_val / 1000.0
144
print("kWh: ", kWh_val)
145
146
if Wflag == 1:
147
WhIn = Wh_val
148
Wflag = 0
149
150
print(WhIn, Wh_val, (Wh_val - WhIn))
151
cost = (Wh_val - WhIn) * 0.2
152
153
print("==========================================================")
154
155
156
#volt_val = str(LineToNeutral.registers)
157
#freq_val = str(Frequency.registers)
158
159
publishOn()
160
sleep(5)
161
162
163
elif (Message == 'OFF'):
164
165
Wflag = 0
166
167
sleep(250/10000000.0)
168
Copied!
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

If everything is correct your code will run without any error and you can see live the data to a AWS cloud and view it on a dashboard.