It is currently April 27th, 2024, 3:39 pm

Help with running count-esque display

Get help with creating, editing & fixing problems with skins
RedFogul
Posts: 5
Joined: June 17th, 2011, 9:14 am

Re: Help with running count-esque display

Post by RedFogul »

I sent jsmorley my status page address, if anyone else wants to have a crack at it let me know and ill send you the link.
NisseDILLIGAF
Posts: 20
Joined: May 31st, 2011, 7:15 am

Re: Help with running count-esque display

Post by NisseDILLIGAF »

Has there been any progress on this?

I found this svg / C script to show graphs of in/out from dd-wrt (/fetchif.cgi?vlan2) adress.
I was thinking about making a Lua script from this... :)

But I'm not very good on programming lua or C..
If there's someone that would like to have a go at it or help out a bit... :)

I think 'function plot_data' is the most interesting...

Code: Select all

<?xml version="1.0" encoding="iso-8859-1"?>
<!--
DD-WRT port of this file based originally on the following:


$Id: graph_cpu.php 41 2006-01-12 18:48:27Z mkasper $
part of m0n0wall (http://m0n0.ch/wall)

Copyright (C) 2004-2005 T. Lechat <dev@lechat.org>, Manuel Kasper <mk@neon1.net>
and Jonathan Watt <jwatt@jwatt.org>.
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

1. Redistributions of source code must retain the above copyright notice,
	this list of conditions and the following disclaimer.

2. Redistributionss in binary form must reproduce the above copyright
	notice, this list of conditions and the following disclaimer in the
	documentation and/or other materials provided with the distribution.

THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
-->
<svg xml:space='preserve' xmlns='http://www.w3.org/2000/svg' 
	xmlns:xlink='http://www.w3.org/1999/xlink'
	width='100%' height='100%' 
	viewBox='0 0 600 300'
	preserveAspectRatio='none'
	onload='init(evt)'
>
<g id='graph'>
	<rect id='bg' x1='0' y1='0' width='600' height='300' fill='white' />

	<text id='graph_in_lbl'  x='60' y='15' fill='green' text-anchor='end'>In</text>
	<text id='graph_out_lbl' x='60' y='35' fill='red' text-anchor='end'>Out</text>

	<text id='graph_in_txt'  x='70' y='15' fill='green'>--</text>
	<text id='graph_out_txt' x='70' y='35' fill='red'>--</text>

	<text id='switch_unit'  x='250' y='15' fill='#435370' cursor='pointer'>Switch to bytes/s</text>
	<text id='switch_scale' x='250' y='35' fill='#435370' cursor='pointer'>Autoscale (follow)</text>

	<text id='error'           x='300' y='125' text-anchor='middle' visibility='hidden' fill='blue'>Cannot get data about interface</text>
	<text id='collect_initial' x='300' y='125' text-anchor='middle' visibility='hidden' fill='gray'>Collecting initial data, please wait...</text>

	<path id='grid' d='M 2 75 L 600 75 M 2 150 L 600 150 M 2 225 L 600 225' stroke='gray' stroke-opacity='0.5' />
	<text id='grid_txt3' x='600' y='223' fill='gray' text-anchor='end'>--</text>
	<text id='grid_txt2' x='600' y='148' fill='gray' text-anchor='end'>--</text>
	<text id='grid_txt1' x='600' y='73' fill='gray' text-anchor='end'>--</text>

	<path id='graph_out' d='' fill='none' stroke='red' stroke-width='1' stroke-opacity='0.8' />
	<path id='graph_in'  d='' fill='none' stroke='green' stroke-width='1' stroke-opacity='0.8' />

	<line id='axis_x' x1='2' y1='299' x2='600' y2='299' stroke='black' />
	<line id='axis_y' x1='1' y1='300' x2='1' y2='0' stroke='black' />
</g>
<script type="text/ecmascript" xlink:href="lang_pack/english.js" />
<script type="text/ecmascript" xlink:href="lang_pack/language.js" />
<script type="text/ecmascript">
<![CDATA[
if (typeof getURL == 'undefined') {
	getURL = function(url, callback) {
		if (!url) throw 'No URL for getURL';

		try {
			if (typeof callback.operationComplete == 'function') {
				callback = callback.operationComplete;
			}
		} catch (e) {}

		if (typeof callback != 'function') {
			throw 'No callback function for getURL';
		}

		var http_request = null;
		if (typeof XMLHttpRequest != 'undefined') {
			http_request = new XMLHttpRequest();
		} else if (typeof ActiveXObject != 'undefined') {
			try {
				http_request = new ActiveXObject('Msxml2.XMLHTTP');
			} catch (e) {
				try {
					http_request = new ActiveXObject('Microsoft.XMLHTTP');
				} catch (e) {}
			}
		}
		if (!http_request) {
			throw 'Both getURL and XMLHttpRequest are undefined';
		}

		http_request.onreadystatechange = function() {
			if (http_request.readyState == 4) {
				callback( 
					{
						success : true,
						content : http_request.responseText,
						contentType : http_request.getResponseHeader("Content-Type")
					}
				);
			}
		}
		http_request.open('GET', url, true);
		http_request.send(null);
	}
}

var SVGDoc = null;
var last_ifin = 0;
var last_ifout = 0;
var last_ugmt = 0;
var max = 0;
var plot_in = new Array();
var plot_out = new Array();

var max_num_points = 120;  // maximum number of plot data points
var step = 600 / max_num_points ;
var unit = share.bytes;
var scale_type = status_band.follow;

var fetch_url='';

function init(evt) {
	/* hacked in fix for all browsers by spectra
	 * he says is 'ugly', and someone may want to redo the 'right' way */
	fetch_url=location.search.split('?');
	fetch_url='/fetchif.cgi?' + fetch_url[fetch_url.length-1];
	/* end hacked in fix */	
	SVGDoc = evt.target.ownerDocument;
	do_translation();
	SVGDoc.getElementById("switch_unit").addEventListener("mousedown", switch_unit, false);
	SVGDoc.getElementById("switch_scale").addEventListener("mousedown", switch_scale, false);	
	fetch_data();
	setInterval('fetch_data()', 1000);
}

function do_translation() {
	SVGDoc.getElementById('graph_in_lbl').firstChild.data = status_band.strin;
	SVGDoc.getElementById('graph_out_lbl').firstChild.data = status_band.strout;
	SVGDoc.getElementById('switch_unit').firstChild.data = status_band.chg_unit + unit + '/s';
	SVGDoc.getElementById('switch_scale').firstChild.data = status_band.chg_scale + ' (' + scale_type + ')';
	SVGDoc.getElementById('error').firstChild.data = status_band.chg_error;
	SVGDoc.getElementById('collect_initial').firstChild.data = status_band.chg_collect_initial;
}

function switch_unit(event) {
	unit = (unit == 'bits') ? share.bytes : 'bits'; 
	SVGDoc.getElementById('switch_unit').firstChild.data = status_band.chg_unit + unit + '/s';
}

function switch_scale(event) {
	scale_type = (scale_type == status_band.up) ? status_band.follow : status_band.up;
	SVGDoc.getElementById('switch_scale').firstChild.data = status_band.chg_scale + ' (' + scale_type + ')';
}

function fetch_data() {
	if (fetch_url) {
		getURL(fetch_url, plot_data);
	} else {
		handle_error();
	}
}

function plot_data(obj) {
	if (!obj.success) return handle_error();  // getURL failed to get data
	if (!obj.content) return handle_error();  // getURL get empty data, IE problem

	// parse incoming data
	// (format: "date" output, newline, proper line of /proc/net/dev)
	var data=obj.content.split("\n");
	var dateStr=data[0];
	//fake timezone cause the real value might confuse JS
	dateStr=dateStr.replace(/ [A-Z]+ /, ' GMT '); 
	var ugmt=(Date.parse(dateStr))/1000;

	data=data[1].split(/\s+|:/);
	while (data[0]!=parseInt(data[0])) {
		data.shift();
		
		if (0==data.length) return;
	}
	var ifin=parseInt(data[0]);
	var ifout=parseInt(data[8]);
	
	if (!isNumber(ifin) || !isNumber(ifout)) {
		return handle_error();
	}

	var diff_ugmt  = ugmt - last_ugmt;
	var diff_ifin  = ifin - last_ifin;
	var diff_ifout = ifout - last_ifout;

	if (diff_ugmt == 0) diff_ugmt = 1;  // avoid division by zero

	last_ugmt = ugmt;
	last_ifin = ifin;
	last_ifout = ifout;
	
	switch (plot_in.length) {
	case 0:
		SVGDoc.getElementById("collect_initial").setAttributeNS(null, 'visibility', 'visible');
		plot_in[0] = diff_ifin / diff_ugmt;
		plot_out[0] = diff_ifout / diff_ugmt;
		return;
	case 1:
		SVGDoc.getElementById("collect_initial").setAttributeNS(null, 'visibility', 'hidden');
		break;
	case max_num_points:
		// shift plot to left if the maximum number of plot points has been reached
		var i = 0;
		while (i < max_num_points) {
			plot_in[i] = plot_in[i+1];
			plot_out[i] = plot_out[++i];
		}
		plot_in.length--;
		plot_out.length--;
	}

	plot_in[plot_in.length] = diff_ifin / diff_ugmt;
	plot_out[plot_out.length]= diff_ifout / diff_ugmt;
	var index_plot = plot_in.length - 1;

	SVGDoc.getElementById('graph_in_txt').firstChild.data = formatSpeed(plot_in[index_plot], unit);
	SVGDoc.getElementById('graph_out_txt').firstChild.data = formatSpeed(plot_out[index_plot], unit);

	// determine peak for sensible scaling
	if (scale_type == status_band.up) {
		if (plot_in[index_plot] > max) max = plot_in[index_plot];
		if (plot_out[index_plot] > max) max = plot_out[index_plot];
	} else if (scale_type == status_band.follow) {
		i = 0;
		max = 0;
		while (i < plot_in.length) {
			if (plot_in[i] > max) max = plot_in[i];
			if (plot_out[i] > max) max = plot_out[i];
			i++;
		}
	}

	var rmax=makeRoundMax(max);

	var scale = 298 / rmax;

	// change labels accordingly
	SVGDoc.getElementById('grid_txt1').firstChild.data = formatSpeed(3*rmax/4, unit);
	SVGDoc.getElementById('grid_txt2').firstChild.data = formatSpeed(2*rmax/4, unit);
	SVGDoc.getElementById('grid_txt3').firstChild.data = formatSpeed(rmax/4, unit);

	var path_in = "M 0 " + (298 - (plot_in[0] * scale));
	var path_out = "M 0 " + (298 - (plot_out[0] * scale));
	for (i = 1; i < plot_in.length; i++) {
		var x = step * i;
		var y_in = 298 - (plot_in[i] * scale);
		var y_out = 298 - (plot_out[i] * scale);
		path_in += " L" + x + " " + y_in;
		path_out += " L" + x + " " + y_out;
	}

	SVGDoc.getElementById('error').setAttributeNS(null, 'visibility', 'hidden');
	SVGDoc.getElementById('graph_in').setAttributeNS(null, 'd', path_in);
	SVGDoc.getElementById('graph_out').setAttributeNS(null, 'd', path_out);
}

function makeRoundMax(max) {
	if (unit == share.bytes) {
		rmax = 1250;
		i = 0;
		while (max > rmax) {
			//dump(i+'\n');
			i++;
			if (i && (i % 4 == 0)) {
				rmax *= 1.25;
			} else {
				rmax *= 2;
			}
		}
	} else {
		rmax = 1024;
		i = 0;
		while (max > rmax) {
			i++;
			if (i && (i % 4 == 0)) {
				rmax *= 1.25;
			} else {
				rmax *= 2;
			}
			
			if (i == 8) rmax *= 1.024;
		}
	}
	return rmax;
}

function handle_error() {
	SVGDoc.getElementById("error").setAttributeNS(null, 'visibility', 'visible');
}

function isNumber(a) {
	return typeof a == 'number' && isFinite(a);
}

function formatSpeed(speed, unit) {
	if (unit == 'bits') return formatSpeedBytes(speed);
	if (unit == share.bytes) return formatSpeedBits(speed);
}

function formatSpeedBits(speed) {
	// format speed in bits/sec, input: bytes/sec
	if (speed < 125000) return Math.round(speed / 125) + " Kbps";
	if (speed < 125000000) return Math.round(speed / 1250)/100 + " Mbps";
	// else
	return Math.round(speed / 1250000)/100 + " Gbps";  // wow!
}

function formatSpeedBytes(speed) {
	// format speed in bytes/sec, input:  bytes/sec
	if (speed < 1048576) return Math.round(speed / 10.24)/100 + " " + share.kbytes + "/s";
	if (speed < 1073741824) return Math.round(speed / 10485.76)/100 + " " + share.mbytes + "/s";
	// else
	return Math.round(speed / 10737418.24)/100 + " " + share.mbytes + "/s";  // wow!
}

]]>
</script>
</svg>

Sorjak
Posts: 1
Joined: August 7th, 2012, 2:43 am

Re: Help with running count-esque display

Post by Sorjak »

Here's a quick python script I wrote to fetch the stuff from dd-wrt's fetchif.cgi page and try to figure out what your wan's total bandwidth is.

Currently, it prints out numbers that get larger as I download things, but they really don't make any sense in relation to what my actual bandwidth should be.

Hope this helps someone trying to do this.

Code: Select all

import os, sys, urllib2, re, time

ROUTER_URL = "YOURROUTERURL"
SCRIPT_PATH = "fetchif.cgi"
INTERFACE = "vlan1"

def getInOut():
    user_agent="Mozilla/5.001 (windows; U; NT4.0; en-US; rv:1.0) Gecko/25250101"
    url = "%s/%s?%s" % (ROUTER_URL, SCRIPT_PATH, INTERFACE)
    
    
    password_mgr = urllib2.HTTPPasswordMgrWithDefaultRealm()
    password_mgr.add_password(None, ROUTER_URL, 'YOURUSERNAME', 'YOURPASSWORD')
    handler = urllib2.HTTPBasicAuthHandler(password_mgr)
    # Create "opener" (OpenerDirector instance).
    opener = urllib2.build_opener(handler)
    # Install the opener.
    # Now all calls to urllib2.urlopen use our opener.
    urllib2.install_opener(opener)
    # Create request.
    req = urllib2.Request(url, None, { 'User-Agent' : user_agent})
    result = urllib2.urlopen(req).read()

    filtered = re.search(r'vlan1:(.*)', result)
    match =  filtered.groups()[0]
    
    proper_nums =  [x for x in match.split(" ") if x]
    
    return {"in" : proper_nums[0], "out" :proper_nums[8]}
    
def main():
    running = 1
    
    oldVal = 0
    while running:
        nums = getInOut()
        
        curout = nums["out"]
        
        print int(curout) - oldVal
        
        oldVal = int(curout)
        
    
    

if __name__ == "__main__":
    main()