Hi Jean-Marc,
First Thanx for the great tools u providing. Great Work !!!
Quick question: Is there any .php or other pooler for meterN that can work with modbus tcp over IP (usually port 502) ?
I have seen that there are scripts out there like the one from gianfrdp /SDM120C that can read the parameters over an USBto RS485 adapter, though in my case I have a meter that has already integrated a modbus tcp server so that i can read the registers directly from ip with tools like modpoll.
Thanx and appreciated !!
Modbus TCP pooler
Re: Modbus TCP pooler
Hi,
Thanks, well i'am not able to write such com app But, if you can retrieve values, that would be easy to integrate them.
Do you have an example of what it is output ?
Thanks, well i'am not able to write such com app But, if you can retrieve values, that would be easy to integrate them.
Do you have an example of what it is output ?
Re: Modbus TCP pooler
Hi,
Thanx for reply. Values are read over Modbus RTU Over TCP/IP from for ex i read 4 holding registers: Pa,Pb,Pc,Total power which are S16 values. I read them using a gui tool in windows called modpoll which allows me to quickly check the value of holding registers. I am not sure how to include an image in the forum to show that to you. i tried button above but didn't work for me. I feel embarrass not knowing in this forum format to attach a pic
Anyway i guess researching a bit u'r docu u do expect a specific format in the .json format like ID(value*unit) which means that i can use some tools to output the values in the expected specific format. This could be this one https://github.com/tallakt/modbus-cli
I'll give it a try with it to see how i can format the output so that it looks like the ones expected by meterN.
Thanx for reply. Values are read over Modbus RTU Over TCP/IP from for ex i read 4 holding registers: Pa,Pb,Pc,Total power which are S16 values. I read them using a gui tool in windows called modpoll which allows me to quickly check the value of holding registers. I am not sure how to include an image in the forum to show that to you. i tried button above but didn't work for me. I feel embarrass not knowing in this forum format to attach a pic

Anyway i guess researching a bit u'r docu u do expect a specific format in the .json format like ID(value*unit) which means that i can use some tools to output the values in the expected specific format. This could be this one https://github.com/tallakt/modbus-cli
I'll give it a try with it to see how i can format the output so that it looks like the ones expected by meterN.
Re: Modbus TCP pooler
Well you can paste RAW data with https://pastebin.com/
You can either choose JSON like {"elect": 1000} or the IEC 62056 data set structure like elect(1000*W), mind that the choose is application wide.
You can write your data formatter in the programming language you are more at ease with (C, CLI, python, ruby, PHP, ...)
You can either choose JSON like {"elect": 1000} or the IEC 62056 data set structure like elect(1000*W), mind that the choose is application wide.
You can write your data formatter in the programming language you are more at ease with (C, CLI, python, ruby, PHP, ...)
Re: Modbus TCP pooler
Hi Jeanmarc,
I was able to write a small comapp that is extracting any register u like using modbus tcp and display it in the IEC62056 format. So basically i used modpoll which is a command line tool being able to read modbus registers over tcp and u can install it practically on any distrib u want to run (https://www.modbusdriver.com/modpoll.html)
So based on this utility i wrote some code for shell that extracts the values from modbus registers, process them a bit and write them into metern txt files under /dev/shm To run this i used this command ->
./pooler485tcp.sh 192.168.100.200 1 14 27 41 45 173 > /dev/null 2>/dev/null &
which basically takes as inputs the registers i need to read from and pools for the values in a continuous loop and push them under /dev/shm/metern2.txt file
I run meterN inside a container on my QNAP NAS and with this pooler it works like a charm. Of course it looks like very newbie like code
and not optimised at all since i run multiple modpoll commands one after the other but in principle with simple modpoll command we can bring any data we want in the IEC62056 format. One can get the idea behind and use it for their own meters where registers are of course different than mine.
Now i am trying to figure out how i can monitor the 3 phase system in meterN very efficiently hence the power meter i have is a bit more advanced(it's a power analyser from Pilot PMAC770 ) and i have a ton of parameters i can read from and use. (Trying to figure out in forum where to take an example on how to monitor 3 phase system)
Anyway many Thanx for the wonderful SW u have and the great job u've done !!!
Content of pooler485tcp.sh
I was able to write a small comapp that is extracting any register u like using modbus tcp and display it in the IEC62056 format. So basically i used modpoll which is a command line tool being able to read modbus registers over tcp and u can install it practically on any distrib u want to run (https://www.modbusdriver.com/modpoll.html)
So based on this utility i wrote some code for shell that extracts the values from modbus registers, process them a bit and write them into metern txt files under /dev/shm To run this i used this command ->
./pooler485tcp.sh 192.168.100.200 1 14 27 41 45 173 > /dev/null 2>/dev/null &
which basically takes as inputs the registers i need to read from and pools for the values in a continuous loop and push them under /dev/shm/metern2.txt file
I run meterN inside a container on my QNAP NAS and with this pooler it works like a charm. Of course it looks like very newbie like code

Now i am trying to figure out how i can monitor the 3 phase system in meterN very efficiently hence the power meter i have is a bit more advanced(it's a power analyser from Pilot PMAC770 ) and i have a ton of parameters i can read from and use. (Trying to figure out in forum where to take an example on how to monitor 3 phase system)
Anyway many Thanx for the wonderful SW u have and the great job u've done !!!
Content of pooler485tcp.sh
Code: Select all
#!/bin/bash
#IP Address of the Modbus power meter i.e 192.168.100.200
ADDRESS="$1"
#Register value for the voltage ex: 40001 coresponding with value 1 as register for modpoll command
V_REGISTER="$2"
#Register value for the Current ex: 40014 corresponding with value 14 as register for modpoll command
I_REGISTER="$3"
#Register value for the Active Power ex: 40027 corresponding with value 27 as a register for modpoll command
P_REGISTER="$4"
#Register value for the Power Factor ex: 40041 corresponding with value 41 as a register for modpoll command
POWER_FACTOR_REGISTER="$5"
#Register value for the Frequency ex: 40045 corresponding with value 45 as a register for modpoll command
F_REGISTER="$6"
#Register value for the Energy ex: 40173 corresponding with value 173 as a register for modpoll command
E_REGISTER="$7"
while [ true ]; do
#modpoll Command to retrieve 3 voltage registers corresponding to V_L1; V_L2; V_L3 in a three phase circuit
CMD_V="./modpoll -m tcp -t4 -r ${V_REGISTER} -c5 ${ADDRESS} -1"
sleep 0.3
#modpoll Command to retrieve 3 current registers corresponding to I_L1; I_L2; I_L3 in a three phase circuit
CMD_I="./modpoll -m tcp -t4 -r ${I_REGISTER} -c5 ${ADDRESS} -1"
sleep 0.3
#modpoll Command to retrieve 4 current registers corresponding to Active_Power_L1; Active_Power_L2; Active_Power_L3; Total_Active_Power in a three phase circuit
CMD_P="./modpoll -m tcp -t4 -r ${P_REGISTER} -c4 ${ADDRESS} -1"
sleep 0.3
#modpoll Command to retrieve 4 current registers corresponding to POWER_FACTOR_L1; POWER_FACTOR_L2; POWER_FACTOR_L3; TOTAL_POWER_FACTOR in a three phase circuit
CMD_POWER_FACTOR="./modpoll -m tcp -t4 -r ${POWER_FACTOR_REGISTER} -c4 ${ADDRESS} -1"
sleep 0.3
#modpoll Command to retrieve 1 current register corresponding to FREQUENCY in a three phase circuit
CMD_FREQUENCY="./modpoll -m tcp -t4 -r ${F_REGISTER} -c1 ${ADDRESS} -1"
sleep 0.3
#modpoll Command to retrieve 1 current register corresponding to TOTAL ENERGY in a three phase circuit
CMD_ENERGY="./modpoll -m tcp -t4:int -r ${E_REGISTER} -c1 ${ADDRESS} -1"
sleep 0.3
#Processing Voltage Values
V_VALUE=$CMD_V
#Getting Modbus Voltage values from Voltage registers
MODBUS_VALUE_V_L1=$($V_VALUE |grep ${V_REGISTER}]: |awk -F: {'print $2'})
MODBUS_VALUE_V_L2=$($V_VALUE |grep $((${V_REGISTER}+1))]: |awk -F: {'print $2'})
MODBUS_VALUE_V_L3=$($V_VALUE |grep $((${V_REGISTER}+2))]: |awk -F: {'print $2'})
MODBUS_VALUE_V_AVERAGE=$($V_VALUE |grep $((${V_REGISTER}+4))]: |awk -F: {'print $2'})
#Scaling Values with defined register scaling unit (ex: for Voltage x 0.01, Unit: V)
VOLTAGE_L1="$((MODBUS_VALUE_V_L1 / 100)).$((MODBUS_VALUE_V_L1 % 100))"
VOLTAGE_L2="$((MODBUS_VALUE_V_L2 / 100)).$((MODBUS_VALUE_V_L2 % 100))"
VOLTAGE_L3="$((MODBUS_VALUE_V_L3 / 100)).$((MODBUS_VALUE_V_L3 % 100))"
VOLTAGE_V_AVERAGE="$(awk "BEGIN {print $MODBUS_VALUE_V_AVERAGE/100}")"
#Display Voltage Values
#echo VOLTAGE_V_L1=$VOLTAGE_L1
#echo VOLTAGE_V_L2=$VOLTAGE_L2
#echo VOLTAGE_V_L3=$VOLTAGE_L3
#echo VOLTAGE_V_AVERAGE=$VOLTAGE_V_AVERAGE
#echo ------------------------
#Processing Current Values
I_VALUE=$CMD_I
#Getting Modbus Current values from Current registers
MODBUS_VALUE_I_L1=$($I_VALUE |grep ${I_REGISTER}]: |awk -F: {'print $2'})
MODBUS_VALUE_I_L2=$($I_VALUE |grep $((${I_REGISTER}+1))]: |awk -F: {'print $2'})
MODBUS_VALUE_I_L3=$($I_VALUE |grep $((${I_REGISTER}+2))]: |awk -F: {'print $2'})
MODBUS_VALUE_I_NEUTRAL=$($I_VALUE |grep $((${I_REGISTER}+3))]: |awk -F: {'print $2'})
MODBUS_VALUE_I_AVERAGE=$($I_VALUE |grep $((${I_REGISTER}+4))]: |awk -F: {'print $2'})
#Scaling Values with defined register scaling unit (ex: for Current x 0.0001, Unit: A)
CURRENT_I_L1="$(awk "BEGIN {print ($MODBUS_VALUE_I_L1/1000)*2}")"
CURRENT_I_L2="$(awk "BEGIN {print ($MODBUS_VALUE_I_L2/1000)*2}")"
CURRENT_I_L3="$(awk "BEGIN {print ($MODBUS_VALUE_I_L3/1000)*2}")"
CURRENT_I_NEUTRAL="$(awk "BEGIN {print ($MODBUS_VALUE_I_NEUTRAL/1000)*2}")"
CURRENT_I_AVERAGE="$(awk "BEGIN {print ($MODBUS_VALUE_I_AVERAGE/1000)*2}")"
#Display Current Values
#echo CURRENT_I_L1=$CURRENT_I_L1
#echo CURRENT_I_L2=$CURRENT_I_L2
#echo CURRENT_I_L3=$CURRENT_I_L3
#echo CURRENT_I_NEUTRAL=$CURRENT_I_NEUTRAL
#echo CURRENT_I_AVERAGE=$CURRENT_I_AVERAGE
#echo --------------------------
#Processing Active Power Values
P_VALUE=$CMD_P
#Getting Modbus Active Power values from Power registers
MODBUS_VALUE_P_L1=$($P_VALUE |grep ${P_REGISTER}]: |awk -F: {'print $2'})
MODBUS_VALUE_P_L2=$($P_VALUE |grep $((${P_REGISTER}+1))]: |awk -F: {'print $2'})
MODBUS_VALUE_P_L3=$($P_VALUE |grep $((${P_REGISTER}+2))]: |awk -F: {'print $2'})
MODBUS_VALUE_P_TOT=$($P_VALUE |grep $((${P_REGISTER}+3))]: |awk -F: {'print $2'})
#Scaling Values with defined register scaling unit (ex: for Active Power x 2, Unit: W)
POWER_P_L1="$(awk "BEGIN {print $MODBUS_VALUE_P_L1*2}")"
POWER_P_L2="$(awk "BEGIN {print $MODBUS_VALUE_P_L2*2}")"
POWER_P_L3="$(awk "BEGIN {print $MODBUS_VALUE_P_L3*2}")"
POWER_P_TOT="$(awk "BEGIN {print $MODBUS_VALUE_P_TOT*2}")"
#Display Active Power Values
#echo POWER_P_L1=$POWER_P_L1
#echo POWER_P_L2=$POWER_P_L2
#echo POWER_P_L3=$POWER_P_L3
#echo POWER_P_TOT=$POWER_P_TOT
#echo ------------------------
#Processing POWER FACTOR Values
POWER_FACTOR_VALUE=$CMD_POWER_FACTOR
#Getting Modbus Power Factor values from Power Factor registers
MODBUS_VALUE_POWER_FACTOR_L1=$($POWER_FACTOR_VALUE |grep ${POWER_FACTOR_REGISTER}]: |awk -F: {'print $2'})
MODBUS_VALUE_POWER_FACTOR_L2=$($POWER_FACTOR_VALUE |grep $((${POWER_FACTOR_REGISTER}+1))]: |awk -F: {'print $2'})
MODBUS_VALUE_POWER_FACTOR_L3=$($POWER_FACTOR_VALUE |grep $((${POWER_FACTOR_REGISTER}+2))]: |awk -F: {'print $2'})
MODBUS_VALUE_POWER_FACTOR_TOT=$($POWER_FACTOR_VALUE |grep $((${POWER_FACTOR_REGISTER}+3))]: |awk -F: {'print $2'})
#Scaling Values with defined register scaling unit (ex: for Power Factor x 0.01)
POWER_FACTOR_L1="$(awk "BEGIN {print $MODBUS_VALUE_POWER_FACTOR_L1/1000}")"
POWER_FACTOR_L2="$(awk "BEGIN {print $MODBUS_VALUE_POWER_FACTOR_L2/1000}")"
POWER_FACTOR_L3="$(awk "BEGIN {print $MODBUS_VALUE_POWER_FACTOR_L3/1000}")"
POWER_FACTOR_TOT="$(awk "BEGIN {print $MODBUS_VALUE_POWER_FACTOR_TOT/1000}")"
#Display Power Factor Values
#echo POWER_FACTOR_L1=$POWER_FACTOR_L1
#echo POWER_FACTOR_L2=$POWER_FACTOR_L2
#echo POWER_FACTOR_L3=$POWER_FACTOR_L3
#echo POWER_FACTOR_TOT=$POWER_FACTOR_TOT
#echo ----------------------------------
#Processing FREQUENCY Values
FREQUENCY_VALUE=$CMD_FREQUENCY
#Getting Modbus Frequency values from Frequency registers
MODBUS_VALUE_FREQUENCY=$($FREQUENCY_VALUE |grep ${F_REGISTER}]: |awk -F: {'print $2'})
#Scaling Values with defined register scaling unit (ex: for Frequency x 0.01)
FREQUENCY="$(awk "BEGIN {print $MODBUS_VALUE_FREQUENCY/100}")"
#Display Frequency Value
#echo FREQUENCY=$FREQUENCY
#echo ----------------------------------
#Processing ENERGY Values
ENERGY_VALUE=$CMD_ENERGY
#Getting Modbus ENERGY values from ENERGY registers
MODBUS_VALUE_ENERGY=$($ENERGY_VALUE |grep ${E_REGISTER}]: |awk -F: {'print $2'})
#Scaling Values with defined register scaling unit (ex: for ENERGY x 0.1; Unit KWh)
ENERGY="$(awk "BEGIN {print $MODBUS_VALUE_ENERGY/10}")"
#Display ENERGY Value
#echo ENERGY=$ENERGY
#echo ----------------------------------
VOLTAGE=$VOLTAGE_V_AVERAGE
CURRENT=$CURRENT_I_AVERAGE
POWER=$POWER_P_TOT
FACTOR=$POWER_FACTOR_TOT
CHECK="OK"
ID=2
if [ "$CHECK" = "OK" ]; then
echo -e "$ID($POWER*W)\n$ID($ENERGY*Wh)\n${ID}_1($VOLTAGE*V)\n${ID}_2($CURRENT*A)\n${ID}_3($FREQUENCY*Hz)\n${ID}_4($FACTOR*F)" > /dev/shm/metern$ID.txt
else
if [ -f /dev/shm/metern$ID.txt ]; then
POWER="0.00"
ENERGY=`sed -n '2p' /dev/shm/metern$ID.txt`
VOLTAGE="0.00"
CURRENT="0.00"
FREQUENCY="0.00"
FACTOR="0.00"
echo -e "$ID($POWER*W)\n$ENERGY\n${ID}_1($VOLTAGE*V)\n${ID}_2($CURRENT*A)\n${ID}_3($FREQUENCY*Hz)\n${ID}_4($FACTOR*F)" > /dev/shm/metern$ID.txt
fi
fi
sleep 2
done
Re: Modbus TCP pooler
Thanks, and thanks for sharing your code, keep up the work 

Who is online
Users browsing this forum: No registered users and 1 guest