Introduction: Centro De Comando Emergencias - Erupção De Vulcão E Terremotos
Projeto acadêmico para atender cenário de colaboração através da internet para divulgação de desastres naturais, onde será possível a detecção dos acontecimentos através de sensores IOT de temperatura, luminosidade, oscilação (tilte) e botão de pânico. Ainda no cenário de colaboração prevemos integração com o Twitter e aplicativos com suporte mqtt para acionamento do alerta.
Diante a possibilidade de diversos meios de entrada na solução, caberá um centro de de operações avaliar se a informação esta correta evitando assim falsos-positivos dos dispositivos automatizado e avaliar a possibilidade de fakenews. Tal tomada de decisão é crucial diante ao pânico que um alarme falso pode gerar.
Como solução de alerta de mensagem estamos considerando o uso do envio de SMS, alerta através de cliente mqtt, email, sirene e twitter.
O projeto contou com uso de recursos da AWS incluindo IOT CORE, EC2 e SNS
Sensores da DragonBord 410c
clientes android mqtt
Sendo todo desenvolvido em python
Autores:
Diego Fernandes dos Santos – diegofs04@gmail.com
Gabriel Piovani Moreira dos Santos – gabriel.piovani@gmail.com
Gustavo Venancio Luz – gustavo_venancio@hotmail.com
Paulo Henrique Almeida Santos – phenrique141@gmail.com
Step 1: Dragonbord 410c - Publicação Dos Sensores - Analogicos
Abaixo o codigo de publicação dos sensores analógicos, os sensores de temperatura e luminosidade estão configurados para que assim que detectarem uma variação fora do padrão pré estabelecido enviarem um alerta através do protocolo mqtt sinalizando um evento.
Este alerta começa a contagem regressiva que pode ser suspensa ou acelerada pelo operador.
O contador para o alerta começa contagem regressiva em 60 seguntos, e todo novo alerta detectado decresce o contador em 20 segundos.
programa rodando dentro da dragon borad 410c
#!/usr/bin/python3
import spidev from libsoc import gpio from time import sleep
# Importa lib para comunicacao com MOSQUITTO import paho.mqtt.client as mqtt
spi = spidev.SpiDev() spi.open(0,0) spi.max_speed_hz=10000 spi.mode = 0b00 spi.bits_per_word = 8
#Usando a porta ADC1 channel_select1=[0x01, 0x80, 0x00]
#Para usar a porta ADC2 use o seguinte vetor de configuração channel_select2=[0x01, 0xA0, 0x00]
def on_connect(mqttc, obj, flags, rc): print("rc: " + str(rc))
def on_message(mqttc, obj, msg): print(msg.topic + " " + str(msg.qos) + " " + str(msg.payload))
def on_publish(mqttc, obj, mid): print("Message Id: " + str(mid) + "\n") pass
# Criamos o client e setamos suas configuracoes mqttc = mqtt.Client()
mqttc.on_message = on_message mqttc.on_connect = on_connect mqttc.on_publish = on_publish
pub = mqtt.Client("grupo3")
# Conexao com localhost, uma vez que testamos fora do labredes. broker_address ="34.230.74.201"
pub.connect(broker_address)
if __name__=='__main__': gpio_cs = gpio.GPIO(18, gpio.DIRECTION_OUTPUT)
with gpio.request_gpios([gpio_cs]): contador=0 adc_value_old=0 adc_value2_old=0 while contador < 50: gpio_cs.set_high() sleep(0.00001) gpio_cs.set_low() rx = spi.xfer(channel_select1) gpio_cs.set_high() contador = contador + 1 adc_value = (rx[1] << 8) & 0b1100000000 adc_value = adc_value | (rx[2] & 0xff) adc_value = ( ((adc_value * 5) / 1024) - 0.5) * 100 print("Temperatura: %f\n" % adc_value) pub.publish("temperatura", str(adc_value)) # teste para acionar contador do alarme, teste ultima leitura + 5%
if adc_value_old==0: adc_value_old=adc_value if adc_value > (adc_value_old*1.05): pub.publish("ALARME", "ON") print ("Alarmado temperatura") adc_value_old=adc_value sleep(1)
gpio_cs.set_high() sleep(0.00001) gpio_cs.set_low() rx = spi.xfer(channel_select2) gpio_cs.set_high() contador = contador + 1 adc_value2 = (rx[1] << 8) & 0b1100000000 adc_value2 = adc_value2 | (rx[2] & 0xff) adc_value2 = adc_value2 /10 print(" Luminosidade: %f\n" % adc_value2) pub.publish("luminosidade", str(adc_value2))
# teste para acionar contador do alarme, teste ultima leitura + 50%
if adc_value2_old==0: adc_value2_old=adc_value2 if adc_value2 > (adc_value2_old*1.5): pub.publish("ALARME", "ON") print ("Alarmado Luminosidade") adc_value2_old=adc_value2 sleep(3)
Step 2: Sensores Digitais - Publicação
código para publicação dos sensores digitais
Os sensores digitais neste projeto foram o tilte que detecta os tremores e o botão para simular o uso de um botão de pânico.
quando detectado uma anomalia ou botão de pânico pressionado a contagem regressiva é iniciada.
programa rodando dentro da dragon borad 410c
from libsoc_zero.GPIO import Button
from libsoc_zero.GPIO import Tilt from time import sleep import paho.mqtt.client as mqtt import sys
def on_connect(mqttc, obj, flags, rc): print("Conectado " + str(rc))
def on_message(mqttc, obj, msg): print(msg.topic + " " + str(msg.qos) + " " + str(msg.payload))
def on_publish(mqttc, obj, mid): # print("Message Id: " + str(mid) + "\n") pass
def detectaTilt(): count = 0 sleep_count = 0 while True: try: tilt.wait_for_tilt(1) except: sleep_count += 1 else: count += 1 sleep_count += 1 if sleep_count > 999: break
print("count:", count) if count>200: pub = mqttc.publish("TERREMOTO", "ON") pub = mqttc.publish("SISMOGRAFO", str(count)) # Criamos o client e setamos suas configuracoes mqttc = mqtt.Client()
mqttc.on_message = on_message mqttc.on_connect = on_connect mqttc.on_publish = on_publish
topic = "grupo3"
# Conexao com localhost, uma vez que testamos fora do labredes. mqttc.connect("34.230.74.201", 1883)
tilt = Tilt('GPIO-A')
btn = Button('GPIO-C')
while True: sleep(0.25) detectaTilt() if btn.is_pressed(): pub = mqttc.publish("PANICO", "ON") print("Botao ON") sleep(1) pub = mqttc.publish("PANICO", "OFF") # else: # pub = mqttc.publish("PANICO", "OFF") # print("Botao OFF")
Step 3: Codigo Para Acionamento Sirene
Codigo para subscrição para acionamento da SIRENE, programa rodando dentro da dragon board 410c
# Importa lib para comunicacao com MOSQUITTO
import paho.mqtt.client as mqtt
from libsoc_zero.GPIO import LED from time import sleep led = LED('GPIO-E') #led.off()
# Define o que fazer ao conectar def on_connect(client, obj, flags, rc): print("Conexão estabelecida com broker")
# Define o que fazer ao receber uma mensagem def on_message(client, obj, message): print("LED " + str(message.payload.decode("utf-8"))) if str(message.payload.decode("utf-8")) == "on": print("Sirene ligada") led.on() else: print("Sierene apagada") led.off()
# IP do broker broker_address = "34.230.74.201"
# Cria o cliente sub = mqtt.Client("grupo3")
sub.connect(broker_address)
sub.on_message = on_message sub.on_connect = on_connect
# Increve no topico sub.subscribe("SIRENE", qos=0)
# Loop para escuta sub.loop_forever()
Step 4: Codigo Twitter - Post
Código para publicação do twitter assim que acionado o alarme.
código rodando na maquina virtual da AWS EC2
#!/usr/bin/env python
#----------------------------------------------------------------------- # twitter-post-status # - posts a status message to your timeline #----------------------------------------------------------------------- import paho.mqtt.subscribe as subscribe
import time
from twitter import *
#----------------------------------------------------------------------- # what should our new status be? #----------------------------------------------------------------------- new_status = "#Terremoto Procure uma zona segura - teste"
#----------------------------------------------------------------------- # load our API credentials #----------------------------------------------------------------------- import sys sys.path.append(".") import config
#----------------------------------------------------------------------- # create twitter API object #----------------------------------------------------------------------- twitter = Twitter(auth = OAuth('senha removida))
#----------------------------------------------------------------------- # post a new status # twitter API docs: https://dev.twitter.com/rest/reference/post/statu... #-----------------------------------------------------------------------
while 1: m = subscribe.simple("twitteralarme", hostname="172.31.83.191", retained=False) if m.topic=="twitteralarme" and str(m.payload.decode("utf-8"))=="on": results = twitter.statuses.update(status = (new_status)+str(time.time())) # print("updated status: %s" % new_status)
Step 5: Centro De Comando
sempre que acionado um dispositivo manual ou detectado um alerta manual do usuário é acionada uma contagem regressiva para envio de mensagem. O operador pode cancelar o envio ou acionar o envio imediato do alerta.
Para uso do dasboard utilizamos um android do telefone para compor a mesa de operação do centro de comando.
código rodando na maquina virtual da AWS EC2
import paho.mqtt.client as paho
import paho.mqtt.subscribe as subscribe import paho.mqtt.publish as publish import json import time import six import ssl from time import sleep
topics = ['#']
gatilho=0 hora_disparo=0 publish.single("ACIONADO", "OFF",qos=1, hostname="172.31.83.191") publish.single("sensor1", "OFF",qos=1, hostname="172.31.83.191") publish.single("sensor2", "OFF", qos=1,hostname="172.31.83.191")
connflag = False
def on_connect(client, userdata, flags, rc): global connflag connflag = True print(connflag) print("Connection returned result: " + str(rc) )
def on_message(client, userdata, msg): # print("teste") print(msg.topic+" "+str(msg.payload))
def on_log(client, userdata, level, buf): print(msg.topic+" "+str(msg.payload))
mqttc = paho.Client("Broker_MSG") mqttc.on_connect = on_connect mqttc.on_message = on_message
awshost = "data.iot.us-east-1.amazonaws.com" awsport = 8883 clientId = "a2rczvc6ni8105" thingName = "Ufscar2018" caPath = "aws-iot-rootCA.crt" certPath = "9e85dfd42a-certificate.pem.crt" keyPath = "9e85dfd42a-private.pem.key" mqttc.tls_set(caPath, certfile=certPath, keyfile=keyPath, cert_reqs=ssl.CERT_REQUIRED, tls_version=ssl.PROTOCOL_TLSv1_2, ciphers=None) mqttc.connect(awshost, awsport, keepalive=60) mqttc.loop_start()
while 1: hora=time.time() sleep(.1) publish.single("LEDTERREMOTO", "on", qos=1,hostname="172.31.83.191")
# if connflag ==True: # mqttc.publish("message", json.dumps({'message':"TERREMOTO"}), qos=1) if gatilho==1: publish.single("TEMPO", str(round(hora_disparo-hora,0)),qos=1, hostname="172.31.83.191") publish.single("LEDTERREMOTO", "on", qos=1,hostname="172.31.83.191") else: publish.single("TEMPO", "99", qos=1,hostname="172.31.83.191") # print(" ") if (hora>hora_disparo) and (gatilho==1): # print("TERREMOTO") # print(connflag) if connflag == True: # mqttc.publish("message", json.dumps({'message':"TERREMOTO"}), qos=1) # mqttc.publish("message","TERREMOTO", qos=1) mqttc.publish("message",json.dumps("TERREMOTO - PROCURE UMA ZONA SEGURA"), qos=1)
# print("teste SNS") # publish.single("LED", "on", hostname="172.31.83.191") publish.single("SIRENE", "on", qos=1,hostname="172.31.83.191") publish.single("TEMPO", "TERREMOTO", qos=1,hostname="172.31.83.191") publish.single("ACIONADO", "OFF", qos=1,hostname="172.31.83.191") publish.single("twitteralarme", "on", qos=1,hostname="172.31.83.191") publish.single("twitter", "TERREMOTO - PROCURE UMA ZONA SEGURA",qos=1, hostname="172.31.83.191") gatilho=0 sleep(5) m = subscribe.simple(topics, hostname="172.31.83.191", retained=False) if m.topic=="ACIONADO" and str(m.payload.decode("utf-8"))=="OFF": gatilho=0 print("cancelado") if m.topic=="medico" and str(m.payload.decode("utf-8"))=="on": if connflag == True: mqttc.publish("medico",json.dumps("MEDICOS - EMERGENCIA TERREMOTO"), qos=1) if m.topic=="bombeiro" and str(m.payload.decode("utf-8"))=="on": if connflag == True: mqttc.publish("bombeiro",json.dumps("BOMBEIRO - EMERGENCIA TERREMOTO"), qos=1) if m.topic=="ambulancia" and str(m.payload.decode("utf-8"))=="on": if connflag == True: mqttc.publish("ambulancia",json.dumps("AMBULANCIA - EMERGENCIA TERREMOTO"), qos=1) if m.topic=="urgente" and str(m.payload.decode("utf-8"))=="on": publish.single("ACIONADO", 1, qos=1,hostname="172.31.83.191") gatilho=1 hora_disparo=time.time()+5 if str(m.payload.decode("utf-8"))=="ON": if gatilho==1: print("acelerado 20") hora_disparo=hora_disparo-20 else: print("Acionado") publish.single("ACIONADO", 1,qos=1, hostname="172.31.83.191") gatilho=1 hora_disparo=time.time()+60
Step 6: Codigo Twitter - Monitoração
código monitoração do twitter, pesquisa post na regiao de sorocaba
código rodando na maquina virtual da AWS EC2
from twitter import *
import config import paho.mqtt.publish as publish
from time import sleep
twitter = Twitter(auth = OAuth(config.access_key, config.access_secret, config.consumer_key, config.consumer_secret))
latitude = -23.546211 longitude = -46.637840 alcance = 50 resultados = 1
publish.single("twitter_alarme", "ON", hostname="34.230.74.201")
result_count = 0 last_id = None flag = 0
for i in range(60): #----------------------------------------------------------------------- # perform a search based on latitude and longitude # twitter API docs: https://dev.twitter.com/rest/reference/get/search... #----------------------------------------------------------------------- try: query = twitter.search.tweets(q = "#Terremoto", geocode = "%f,%f,%dkm" % (latitude, longitude, alcance), max_id = last_id) print("leu")
except: print("erro acesso twitter") break
for result in query["statuses"]:
#-----------------------------------------------------------------------
# only process a result if it has a geolocation #----------------------------------------------------------------------- if result["geo"]: result_count += 1 last_id = result["id"] sleep(1) if result_count == resultados: flag += 1 publish.single("twitter_alarme", "ON", hostname="34.230.74.201") publish.single("twitter", "TERREMOTO - DETECTADO", hostname="34.230.74.201") break
Step 7: Estrutura AWS
Utilizamos uma maquina virtual rodando ubuntu na estrutura AWS EC2
Utilizamos a AWS IOT CORE para o serviço de MQTT onde configuramos as ações conforme o tipo de mensagem
Utilizmos topicos do AWS SNS que eram acionados pelo AWS IOT CORE