Mais do que nunca, somos dependentes da Internet. Dependemos dela para ler notícias, nos correspondermos, pagar contas, fazer compras e por aí vai. Isso sem falar na onda do IoT (Internet of Things – Internet das Coisas em tradução livre), a qual baseia sua existência na conectividade à rede. Entretanto, nem sempre temos à disposição uma conexão boa à Internet, comprometendo assim muitas de nossas atividades e inviabilizando o uso equipamentos do contexto de IoT.

Pois bem, como saber qual a qualidade e/ou estabilidade de sua Internet? É exatamente disso que este artigo se trata: como monitorar DownTime.
Além disso, o projeto também permite disponibilizar, à nível global (através da rede social Twitter e da plataforma cloud ThingSpeak), as informações obtidas. Desta forma, além de saber a quantas anda sua qualidade de conectividade, você contribuirá para todos terem ideia das operadoras de Internet que oferecem menos qualidade de conectividade à Internet.

Este projeto pode ser usado em Linux (inclusive em dispositivos embarcados), o que aumenta consideravelmente suas possibilidades de uso.

 

Pré-requisitos

 

Para reproduzir o projeto aqui proposto, há os seguintes pré-requisitos:

  • Conhecimento básico de Linux
  • Conhecimento básico de Python
  • Conhecimento básico sobre redes de computadores
  • Ter ao menos ouvido falar de ThingSpeak e Twitter (se não conheçe algum destes, agora é uma ótima hora para conhecer!)

 

Motivação do projeto

 

A disponibilidade de Internet por parte das operadoras é garantida pelo artigo 46, resolução nº614/2013 da ANATEL (mais detalhes aqui). Exceto em caso de interrupção programada com aviso prévio (de, no mínimo, uma semana), todo o período de indisponibilidade de Internet maior que 30 minutos deve ser descontado da fatura mensal.

E isso faz todo o sentido, afinal estamos pagando por um serviço, logo nada mais justo esperar que este seja entregue corretamente.

Portanto, a motivação deste projeto é, além de monitorar as piores operadoras de Internet do Brasil, ter meios de fazer valer nossos direitos como consumidores!

Estratégia do projeto

 

A estratégia do projeto é simples: pingar um local confiável (na rede externa / Internet) e avaliar a resposta obtida. Ou seja:

  • Houve resposta ao ping: a conectividade à Internet está ok!
  • Sem resposta ao ping: pois é, a Internet se foi.

 

O segredo da coisa está no tempo entre os pings: para evitar ser bloqueado no servidor onde você está pingando por envio excessivos de pings /pacotes ICMP (acredite ou não, isso se o tempo for muito curto, isso é considerado um ataque DDoS, por mais pré-histórica que esta ideia seja). Portanto, como limite seguro, este projeto considera seguro um intervalo entre pings de 20 segundos. Por consequencia, o menor DownTime comtabilizável será 20 segundos.

Como alvo dos pings, deve ser escolhido o local mais confiável possível. No caso do projeto, escolhi o famoso Google, mais precisamente, o servidor DNS dele (IP 8.8.8.8). Motivo: eles devem receber tantas requisições / segundo lá que dificilmente irão bloquear algo nesta linha, levando o risco de bloqueio por número excessivos de pacotes ICMP a praticamente zero.

A partir do momento que pode-se comprovar o funcionamento ou não da Internet, é possível contabilizar o Downtime e fazer o que desejar com esta informação (neste caso, será enviada ao Twitter e ThingSpeak o Downtime, “dedurando” a operadora de Internet).

Vale ressaltar que o Tweet será, na verdade, gerado pelo próprio ThingSpeak (através do acesso de sua API HTTPS). Dessa forma, com uma simples requisição HTTPS e sem necessidade de biblioteca ou recursos mais específicos, pode-se gerar os Tweets do projeto. Além disso, todos os DownTimes contabilizados irão ser salvos no seu canal ThingSpeak, o que permite acompanhar o histórico de DownTimes de determinada situação.

Preparando o terreno

 

Antes da implementação do projeto em si, é necessário serem feitas algumas coisas antes:

– Conta no Twitter

A primeira coisa a ser feita é criar uma conta no Twitter dedicada ao projeto. Não há segredo nenhum aqui: basta visitar o site do Twitter e fazer uma conta comum.

– Conta no ThingSpeak e criação de um canal

 

Será preciso uma conta no ThingSpeak e, posteriormente, a criação de um canal. Para isso, recomendo a visualização do vídeo abaixo. O vídeo é do Pedro Minatel, um grande nome do IoT no Brasil.

Importante: ao criar o canal, anote / salve a Write Key API dele. Isto será fundamental para envios de informações ao canal (algo que será detalhado mais a frente neste artigo).

– Interligando Twitter ao ThingSpeak

Conforme foi falado na estratégia do projeto, o ThingSpeak é quem, na realidade, irá gerar o Tweet. Portanto, será necessário fazer a integração de sua conta ThingSpeak com a conta do Twitter do projeto. Para isso, siga o procedimento abaixo:

  • Faça login no Twitter e permaneça logado em uma das abas do navegador
  • Abra uma nova aba e faça login no ThingSpeak. Uma vez logado, clique em Apps e depois em ThingTweet. Observe a figura abaixo:

    Figura 1 - Apps do ThingSpeak (destaque ao ThingTweet)

    Figura 1 – Apps do ThingSpeak (destaque ao ThingTweet)

  • Na tela que abrir, no lado direito da mesma, observar a sessão Example API Endpoint. Lá conterá uma informação similar a da figura 2.
Figura 2 - dados para requisição HTTPS (Tweetar com o ThingSpeak)

Figura 2 – dados para requisição HTTPS (Tweetar com o ThingSpeak)

Anote / guarde estas informações, principalmente a API_KEY. Isto será utilizado mais adiante neste projeto.

  • Clique em ThingTweet. Na página que abrir, clique no botão Link Twitter Account. Siga as instruções da tela e a integração está feita!

 

Talk is cheap. Show me the code!

 

É chegada a hora do código! O código deste projeto foi feito em linguagem Python. Este projeto pode rodar basicamente em qualquer dispositivo que utilize Linux, seja ele embarcado ou não.

import httplib
import urllib
import os
import time

#variaveis globais
ContaTwetterDoSeuProvedorDeInternet = "@NEToficial"
NomeDaSuaCidade = "Sao Bernardo do Campo - SP"
APIKeyThingSpeak = 'KKKKKKKKKKKKKKKK'   #substitua KKKKKKKKKKKKKKKK pela sua api_key
WriteAPIKey = 'WWWWWWWWWWWWWWWW'   #substitua WWWWWWWWWWWWWWWW pela sua write api key do seu canal

#Downtime monitor variables
TimestampInicial_DownTime = 0
EstaOffline = 0
DownTimeTotal = 0
ArquivoRelatorioDowntime = "DownTimeReport.txt"
NumeroDowntimesDetectados = 0
NumeroTentativas = 1

def VerificaERegistraDowntime(res):
	global EstaOffline
	global TimestampInicial_DownTime
	global DownTimeTotal
	global ArquivoRelatorioDowntime
	global NumeroDowntimesDetectados
	global NumeroTentativas

	if (res == 0):
		print " "
		print "Internet esta on!"
	else:
		print " "
		print "Internet esta off..."

        #Verifica se internet estava on e agora esta off
	if ((res!=0) and (EstaOffline == 0)):
		TimestampInicial_DownTime = time.time()
		EstaOffline = 1
	        return

        #Verifica se internet estava off e agora esta on
	if ((res == 0) and (EstaOffline == 1)):
		DownTimeTotal = time.time() - TimestampInicial_DownTime
		
		if (DownTimeTotal > (1800)):  #se maior que 30min, deve ser descontada da fatura
			StringDT =  "DownTime detectado (>30min): "+str(DownTimeTotal)+" segundos offline\n"
		else:	
			StringDT =  "DownTime detectado (<30min): "+str(DownTimeTotal)+" segundos offline\n"
	        print StringDT
		TxtFile = open(ArquivoRelatorioDowntime,"a")
		TxtFile.write(StringDT)
		TxtFile.close()
        	NumeroDowntimesDetectados = NumeroDowntimesDetectados + 1
		EstaOffline = 0
	        EnviaTweet(DownTimeTotal)
		EnviaDownTimeThingSpeak(DownTimeTotal)
		return

def EnviaTweet(DuracaoDT):
	global ContaTwetterDoSeuProvedorDeInternet
	global NomeDaSuaCidade
	global APIKeyThingSpeak
        
        
        StringParaTwettar = ContaTwetterDoSeuProvedorDeInternet+", foi detectado um downtime de "+str(DuracaoDT)+" segundos. Estou na cidade de "+NomeDaSuaCidade+". #DownTimeDetectado"
	params = urllib.urlencode({'api_key': APIKeyThingSpeak, 'status': StringParaTwettar})  
	conn = httplib.HTTPConnection("api.thingspeak.com:80")
	conn.request("POST","/apps/thingtweet/1/statuses/update",params)
	resp = conn.getresponse()
	conn.close()

def EnviaTweetDownTimeIniciado():
	global APIKeyThingSpeak

    	StringParaTwettar = "Monitor de DownTime iniciado!"
	params = urllib.urlencode({'api_key': APIKeyThingSpeak, 'status': StringParaTwettar})  
	conn = httplib.HTTPConnection("api.thingspeak.com:80")
	conn.request("POST","/apps/thingtweet/1/statuses/update",params)
	resp = conn.getresponse()
	conn.close()
	
def EnviaDownTimeThingSpeak(DuracaoDT):	  	
	global WriteAPIKey

	params = urllib.urlencode({'field1': str(DuracaoDT),'key':WriteAPIKey})
    	headers = {"Content-typZZe": "application/x-www-form-urlencoded","Accept": "text/plain"}
	conn = httplib.HTTPConnection("api.thingspeak.com:80")
    	conn.request("POST", "/update", params, headers) # Tenta fazer uma requisicao
	resp = conn.getresponse()


#----------------------
#  PROGRAMA PRINCIPAL
#----------------------

EnviaTweetDownTimeIniciado()

while True:
	try:
		os.system("clear")
       		print "---------------------------"
	    	print "     DownTime Monitor      "
      		print "---------------------------"
	        print " "
		print "Tentativa #"+str(NumeroTentativas)+" - "+str(NumeroDowntimesDetectados)+" downtime(s) detectados"
	        print " "

		PingResult = os.system("ping -c 1 8.8.8.8")
	        VerificaERegistraDowntime(PingResult)
		time.sleep(20) 
      		NumeroTentativas = NumeroTentativas + 1
	except (KeyboardInterrupt):
		print "Aplicacao encerrada."
		exit(1)

 

 

Se preferir, pode baixar o código-fonte do meu repositório no GitHub clicando aqui.

Para executar o código, basta salvar o código come extensão .py e utilizar o seguinte comando:

sudo python NOMEDOSEUARQUIVO.py


Observação:
o sudo neste caso é necessário pois, em algumas distribuições, o envio de pacotes ICMP (os pings) não é liberado a usuários comuns.

 

Resultado

 

Como resultado, segue abaixo a conta Twitter que criei e dados do canal ThingSpeak que criei para este fim. Ambos contém todos os Downimes registrados)

Link para conta Twitter

[iframe_loader src=”https://thingspeak.com/channels/208858/charts/1″]

Em suma, quanto mais pessoas utilizarem este projeto, teremos no Twitter uma fonte de informação cada vez melhor sobre as operadoras e locais com mais Downtime no Brasil. Para isso, bastará procurar pera hashtag #DownTimeDetectado no Twitter! Portanto, quanto mais pessoas usarem, melhor. Que tal contribuir com esta avaliação da Internet brasileira e, de quebra, fazer valer seus direitos de consumidor ?

Trabalhos futuros

 

Como acontece com todo e qualquer projeto existente, sempre há possibilidades de trabalhos futuros / melhorias. Se alguém quiser melhorar este projeto (sinta-se à vontade para isso!), sugiro considerar:

  • Uma forma de inicializar este projeto junto com seu sistema operacional, de forma que este execute em “background”.
  • Incrementar a análise por ele feita, incluindo também avaliação a velocidade de Internet.
  • Essa é para os que gostam de um hacking um pouco mais pesado: os roteadores utilizam, em sua maioria, a distribuição Linux OpenWRT. Apesar de objetivar uso em redes, esta distribuição suporta Python e as bibliotecas utilizadas aqui neste projeto.
    Sendo assim, sugiro implementar este projeto direto no roteador (incluindo: acessar via ssh, instalar bibliotecas, fazê-lo inicializar automaticamente com o script, etc.). Dessa forma, o seu próprio roteador “avisará” quando a Internet cair.

 

Agradecimentos

 

Segue aqui um agradecimento especial ao Cleiton Bueno por toda a ajuda e paciência em me ajudar neste projeto. Muito obrigado mesmo!

Gostou do artigo? Tem dúvidas? Tem críticas? Comente abaixo!


Pedro Bertoleti

Informações completas em: http://pedrobertoleti.com.br/index.php/sobre/

4 comentários

Almir Braggio · 30/01/2017 às 11:27 am

Bacana integrar com o ThingSpeak.
No início do ano passado, conheci este projeto que faz a mesma coisa, com o intuito de reclamar da operadora quando sua velocidade é menor do que a contratada. https://github.com/james-atkinson/speedcomplainer
Na época usei como base e deixei no R.Pi testando a minha conexão, que era péssima. Foi um dos motivos da minha troca de operadora.

    phfbertoleti · 30/01/2017 às 12:26 pm

    Almir, boa tarde.

    Muito obrigado pela leitura e pelo comentário!
    Legal conhecer este projeto que você indicou. Não sabia da existência do mesmo. E muito interessante saber que este foi decisivo pra você trocar de operadora (espero que o projeto deste artigo também ajude as pessoas a tomarem suas decisões neste aspecto).

    Atenciosamente,
    Pedro Bertoleti

Guilherme · 30/01/2017 às 11:57 am

Amigo, legal sua ideia, ando sofrendo com minha internet aqui, vou usar para analisar e vou jogar no ThingSpeak, não uso Twitter então vou deixar apenas no ThingSpeak. Outra coisa importante que faltou é: Como fazer o script ser executado em segundo plano automaticamente pelo sistema operacional (Windows, Linux e Mac).

Valeeu!

    phfbertoleti · 30/01/2017 às 12:25 pm

    Guilherme, boa tarde.

    Muito obrigado pela leitura e pelo comentário!
    Quanto a deixar o script / processo do script ser executado em segundo plano (ou, em alguns casos, iniciar automaticamente quando o sistema operacional for iniciado), eu nem falei sobre pois cada sistema operacional possui uma maneira disto ser feito. Porém, vou acrescentar esta observação no artigo, achei importante sua colocação, obrigado.

    Atenciosamente,
    Pedro Bertoleti

Os comentários estão fechados.