La primer opción fue escanear el tráfico directamente de la red e ir contando el tamaño de los datos transmitidos. Sin embargo, esta solución no funciono, ya que al estar conectados al ruteador, sólo recibimos paquetes que están destinados al Raspeberry o paquetes broadcast.
La segunda opción fue conectarse directamente al ruteador y extraer la información del tráfico del día. Para ello, primero nos conectamos manualmente al ruteador y monitoreamos el tráfico usando Wireshark, esto nos permitió aprender que el ruteador usa autenticación básica y que la página que contiene la información del tráfico se llama traffic.htm. Esto también nos ayudo a inspeccionar el contenido de traffic.htm y observar que una variable de javascript contiene la información que necesitamos.
Con toda esta información, la lógica del programa es muy sencilla.
- Inicializar IO y prender todos los LEDs durante 3 segundos para diagnosticar LEDs en mal estado.
- Ciclo infinito:
- Obtener traffic.htm del ruteador
- Extraer tráfico del día
- Desplegar en formato binario usando los LEDs el tráfico del día en cientos de MB
El código en python es el siguiente:
import urllib2
import re
import base64
import time
import RPi.GPIO as GPIO
def get_router_page():
theurl = 'http://192.168.1.1/traffic.htm'
username = 'admin'
password = 'your_password'
req = urllib2.Request(theurl)
# First try without username/password
try:
handle = urllib2.urlopen(req)
except IOError, e:
pass
else:
return handle.read()
# Now try with authentication
base64string = base64.encodestring(
'%s:%s' % (username, password))[:-1]
authheader = "Basic %s" % base64string
req.add_header("Authorization", authheader)
try:
handle = urllib2.urlopen(req)
except IOError, e:
print e
return None
return handle.read()
def get_traffic_in_MB(page):
for line in page.split('\n'):
match = re.search(
r'\s*var\s*traffic_today_total\s*=\s*"(.*)"\s*;\s*',
line)
if match:
return match.group(1).replace(',','')
return None
def is_bit_set(value, bit):
mask = 1 << bit
return (value & mask)
def display_traffic(traffic_MB):
traffic_in_100_MB = int(float(traffic_MB) / 100)
if traffic_in_100_MB > 31:
traffic_in_100_MB = 31
print traffic_in_100_MB
GPIO.output(LED_0_PIN,is_bit_set(traffic_in_100_MB,0))
GPIO.output(LED_1_PIN,is_bit_set(traffic_in_100_MB,1))
GPIO.output(LED_2_PIN,is_bit_set(traffic_in_100_MB,2))
GPIO.output(LED_3_PIN,is_bit_set(traffic_in_100_MB,3))
GPIO.output(LED_4_PIN,is_bit_set(traffic_in_100_MB,4))
def init_IO():
# Init outputs
GPIO.setmode(GPIO.BCM)
GPIO.setup(LED_0_PIN,GPIO.OUT)
GPIO.setup(LED_1_PIN,GPIO.OUT)
GPIO.setup(LED_2_PIN,GPIO.OUT)
GPIO.setup(LED_3_PIN,GPIO.OUT)
GPIO.setup(LED_4_PIN,GPIO.OUT)
# Test all leds
GPIO.output(LED_0_PIN,True)
GPIO.output(LED_1_PIN,True)
GPIO.output(LED_2_PIN,True)
GPIO.output(LED_3_PIN,True)
GPIO.output(LED_4_PIN,True)
time.sleep(3)
GPIO.output(LED_0_PIN,False)
GPIO.output(LED_1_PIN,False)
GPIO.output(LED_2_PIN,False)
GPIO.output(LED_3_PIN,False)
GPIO.output(LED_4_PIN,False)
LED_0_PIN = 23
LED_1_PIN = 24
LED_2_PIN = 25
LED_3_PIN = 8
LED_4_PIN = 7
init_IO()
while True:
page = get_router_page()
if page is not None:
traffic = get_traffic_in_MB(page)
if traffic is not None:
display_traffic(traffic)
time.sleep(60)
GPIO.cleanup()
Saludos.









