Creating a chart based on TP-Link modem statistics

Beginner here…
I can get IP based internet or LAN usage statistics of home network clients from the TP-Link VDSL-Modem-Switch VR2600 using curl commands. What i am trying to achieve is to create a bar or line chart using these stats based on IP addresses. So that i will be able to follow up which device is using the LAN or internet most at a given time. Using curl in a bash script i can get the following stats:

[0,0,0,0,0,0]0
enable=1
interval=10
action=0
[1,0,0,0,0,0]1
ipAddress=3232235848
macAddress=XX:XX:XX:XX:XX:XX
totalPkts=201
totalBytes=22914
currPkts=0
currBytes=0
currIcmp=0
currUdp=0
currSyn=0
currIcmpMax=0
currUdpMax=15
currSynMax=0
[2,0,0,0,0,0]1
ipAddress=3232235829
macAddress=XX:XX:XX:XX:XX:XX
totalPkts=972
totalBytes=98730
currPkts=0
currBytes=0
currIcmp=0
currUdp=0
currSyn=0
currIcmpMax=0
currUdpMax=14
currSynMax=4
[3,0,0,0,0,0]1
ipAddress=3232235842
macAddress=XX:XX:XX:XX:XX:XX
totalPkts=154566
totalBytes=15116490
currPkts=0
currBytes=0
currIcmp=0
currUdp=0
currSyn=0
currIcmpMax=9
currUdpMax=58
currSynMax=60
[4,0,0,0,0,0]1
ipAddress=3232235856
macAddress=XX:XX:XX:XX:XX:XX
totalPkts=13509
totalBytes=1551437
currPkts=0
currBytes=0
currIcmp=0
currUdp=0
currSyn=0
currIcmpMax=1
currUdpMax=60
currSynMax=17
[5,0,0,0,0,0]1
ipAddress=3232235885
macAddress=XX:XX:XX:XX:XX:XX
totalPkts=1100
totalBytes=111320
currPkts=0
currBytes=0
currIcmp=0
currUdp=0
currSyn=0
currIcmpMax=0
currUdpMax=40
currSynMax=37

Now, can aynone direct me into a path to how i can use these stats in openHAB? Should i convert the file into an XML and use XLST, or any other method to get the values into persistence and draw a graph? The required items are: ipAddress, totalPkts, totalBytes, currPkts and currBytes.

Thanks…

The approach I would take, given you have control over the format of the data, would be to format the data as JSON. Then define your Items for each field you want (i.e. for each IP you need separate items for the fields you care about) and use JSONPATH transform to extract the data you want.

Then I’d use the HTTP binding to periodically poll the URL for the data.

Configure persistence on the Items created above and you should be good to go.

This would be the least amount of coding and work on the OH side of things, in my opinion.

Of course you can do this with XML and XPATH or XSLT as well but, as someone who has used XML for over a decade, I gotta say I like JSON better.

1 Like

Thanks a lot Rich, JSON seems like a better choice indeed. I will inform you all after i manage to do what i am after…

OK, i decided to use python3 and JSON to get the statistics from the router and parse it, then create a JSON file to be used by Google Charts into a web page. And i am using Webview in OH2 to display the results under a rule which fires the python script every 5 minutes. In case if anyone needs it:

vr2600.py

import urllib.request
from urllib.error import HTTPError
import json
import ipaddress

aa = {}
ab = {}
ac=[]
ip_name={}

url = 'http://192.168.1.1/cgi?1&5' # Set destination URL here
params='[STAT_CFG#0,0,0,0,0,0#0,0,0,0,0,0]0,0\r\n[STAT_ENTRY#0,0,0,0,0,0#0,0,0,0,0,0]1,0\r\n'
params=params.encode('utf8')
post_fields = {'Referer': 'http://192.168.1.1/','Cookie':'Authorization=Basic _password_base64_','Content-Type': 'text/plain; charset=UTF-8'}     # Set POST fields here

request = urllib.request.Request(url, data=params, headers=post_fields)
try:
    response = urllib.request.urlopen(request)
except HTTPError as e:
    content = e.read()
    
response_txt=response.read().decode('utf8')

words=response_txt.splitlines()
with open('/etc/openhab2/transform/ipAddress.json', 'r') as fc:
    ip_name = json.load(fc)

for line in words:
    try:
        aa = dict(x.split('=') for x in line.split(','))
        if line.startswith('ipAddress'):
            aa['ipAddress'] = str(ipaddress.IPv4Address(int(aa['ipAddress'])))
            host_name = ip_name.get(aa['ipAddress'], "empty")
            if host_name != 'empty':
                aa['ipAddress'] = host_name
            ab = aa
        elif line.startswith('currSynMax'):
            ab.update(aa)
            ac.append(ab)
        else:
            ab.update(aa)       
    except:
        pass

jsonarray = json.dumps(ac, ensure_ascii=False, indent=4)
with open('/web/vr2600stat.json', 'w') as f:
    f.write (jsonarray) 

ipAddress.json

{
"192.168.1.90": "Host1", 
"192.168.1.54": "Host2",
"192.168.1.1": "TP-Link",
"192.168.1.50": "Host3",
"192.168.1.51": "Host4",
"192.168.1.52": "Host5",
"192.168.1.53": "Host6",
"192.168.1.55": "Host7",
"192.168.1.56": "Host8"
}

vr2600stat.html:

<html>
  <head>
  <meta content = "text/html; charset = UTF-8" http-equiv = "content-type">

<div id="chart" style="width: 100%"></div>

<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script src="https://www.google.com/jsapi"></script>

<script>


google.load('visualization', '1', {'packages':['corechart', 'bar', 'table']});

google.setOnLoadCallback(drawChart);

function drawChart() {
    $.ajaxSetup({ cache: false });
    $.get('http://192.168.1.90/json/vr2600stat.json', function(response) {
        
        var chartData = [];
        for(var idx = 0; idx < response.length; ++idx) {
            var item = response[idx];
            chartData.push([item.ipAddress, item.macAddress, Number(item.totalPkts), Number(item.totalBytes), Number(item.currPkts), Number(item.currBytes), Number(item.currIcmp), Number(item.currUdp), Number(item.currSyn), Number(item.currIcmpMax), Number(item.currUdpMax), Number(item.currSynMax) ]);
        }

        // Create the data table.
        var data = new google.visualization.DataTable();
        data.addColumn('string', 'IP Address');
        data.addColumn('string', 'MAC');
        data.addColumn('number', 'Total Packets');
        data.addColumn('number', 'Total Bytes');
        data.addColumn('number', 'currPkts');
        data.addColumn('number', 'currBytes');
        data.addColumn('number', 'currIcmp');
        data.addColumn('number', 'currUdp');
        data.addColumn('number', 'currSyn');
        data.addColumn('number', 'currIcmpMax');
        data.addColumn('number', 'currUdpMax');
        data.addColumn('number', 'currSynMax');
        
        data.addRows(chartData);
		data.sort({column: 5, desc: true});
		var view = new google.visualization.DataView(data);
			view.setRows(data.getFilteredRows([
  			{column: 5, minValue: 100}
		]));
		
		//data.sort({column: 3, desc: true});
		var view2 = new google.visualization.DataView(data);
			view2.setRows(data.getFilteredRows([
  			{column: 3, minValue: 500000}
		]));
		
		
        var options = {
            title: 'VR2600 Statistics',
            bars: 'vertical', // Required for Material Bar Charts.
            series: {
                0: { axis: 'IP_Address' },
                1: { axis: 'currBytes' }
            },
            axes: {
                x: {
                    IP_Address: {label: 'Address'},
                    currBytes: {side: 'top', label: 'Bytes'}
                }
            }
        };

        //create and draw the chart from DIV
        //var chart = new google.visualization.BarChart(document.getElementById('chart_div'));
        barChart = new google.visualization.ChartWrapper({
            'chartType': 'BarChart',
            'containerId': 'chart_div',
            'dataTable': view,
            'options': {
            'legend': 'none',
            'width': '100%',
            'height': '100%',
            'vAxis': {title: "Host"},
            'hAxis': {title: "Current Bytes"},
            'fontSize': 14,
            'showRowNumber' : true,
            },
            'view': {'columns': [0,5]}
        });
        //barChart.draw(data, options);
		barChart.draw();

		barChart2 = new google.visualization.ChartWrapper({
            'chartType': 'ColumnChart',
            'containerId': 'chart_div2',
            'dataTable': view2,
            'options': {
            'legend': 'none',
            'colors': ['#800000'],
            'is3D': 'true',
            'width': '100%',
            'height': '100%',
            'vAxis': {title: "Total Bytes", format: 'short'},
            'hAxis': {title: "Host", slantedText: 'true', slantedTextAngle: '30', showTextEvery: '1'},
            'fontSize': 14,
            'showRowNumber' : true,
            },
            'view': {'columns': [0,3]}
        });
        //barChart.draw(data, options);
		barChart2.draw();
				
        table = new google.visualization.ChartWrapper({
            'chartType': 'Table',
            'containerId': 'table_sort_div',
            'dataTable': data,
            'options': {
            'width': '100%',
            'height': '100%',
            'fontSize': 14,
            'showRowNumber' : true,
            },
            'view': {'columns': [0,3,5]}
        });
		table.draw();
		

    }, 'json');
}


</script>




  </head>

  <body>
    <!--Div that will hold the chart-->
    <div id="chart_div"></div>
    <div id="chart_div2"></div>
    <div id="table_sort_div"></div>
  </body>
</html>

And the result is: