Plataformas para a Internet das Coisas Paulo F. Pires1, Flavia C. Delicato1, Thais Batista2, Thomaz Barros1, Everton Cavalcante1,3, Marcelo Pitanga1 1DCC/PPGI, Universidade Federal do Rio de Janeiro, Rio de Janeiro, Brasil 2DIMAp, Universidade Federal do Rio Grande do Norte, Natal, Brasil 3IRISA-UMR CNRS/Université de Bretagne-Sud, Vannes, França Plataformas de middleware para IoT Carriots • Plataforma que utiliza serviços de nuvem para gerenciar dados providos por dispositivos • Platform as a Service (Paas) desenvolvida para conexão de dispositivos (M2M) no contexto de IoT • Coleta e armazena qualquer tipo de dado de quaisquer dispositivo • Permite a construção de aplicações • Capacidade de suportar milhares de dispositivos conectados à uma mesma aplicação Sistemas Dispositivos Pessoas Produtos conectados 3 Carriots: Construindo um Projeto de IoT Sistemas de TI Personalizados Front end Apresentação Internet Plataforma Aplicação (BD, middleware e motor de regras) Internet Hardware Sensores e Atuadores “Coisas” 4 Carriots: Construindo um Projeto de IoT Serviços Personalizados HTTP REST Serviços Web HTTPS Interface Web HTTP API HTTP 3G/4G/Ethernet Zigbee/ Rádio Gateway Gateway Outras 5 APIs Carriots: Dispositivos • Sensores ― Coletam os dados brutos lidos por um dispositivo ― Por exemplo: temperatura, presença, vento, campos magnéticos, etc. • Atuadores ― Interagem com o mundo físico agindo sobre ele ― Por exemplo: abrir/fechar portas, exibir mensagens, acender/apagar luzes, enviar sinais, etc. 8 Carriots: Dispositivos • No contexto de um projeto de IoT, os objetos devem ser capazes de se comunicar e interagir pela Internet ― Autossuficientes o Modem GPRS/3G/4G embutido ― Sensor + Gateway o Serial (e.g., RS 485) ou rádio (e.g., 868MHz) + gateway de comunicação HTTP 3G/4G/Ethernet Gateways ― Rede de sensores + Gateway • Protocolos de Comunicação ― HTTP RS 485 Zigbee ― JSON ou XML ― API REST 9 Carriots: Dispositivos • Exemplo: enviando dados de um sensor de presença de veículo estacionado 10 Carriots: Plataforma • API REST ― Seguindo padrões da Internet, a plataforma implementa uma API REST sobre HTTPS ― Recebe grande quantidade de dados dos dispositivos ― Plena capacidade de interação entre a plataforma e os painéis de controle personalizados, dashboards, etc. ― Exemplo: Sensores de estacionamento enviando status (ocupada ou livre) de uma vaga. Painel de controle personalizado é utilizado para gerenciamento 11 Carriots: Plataforma • BD Big Data ― Grandes quantidades de dados são armazenadas em uma arquitetura de big data schemaless ― Provê flexibilidade para o gerenciamento de dados dos mais diversos dispositivos ― Exemplo: temperatura, posicionamento geográfico, etc. 12 Carriots: Plataforma • Gerenciamento de Projetos e Dispositivos ― Projetos podem ser organizados para atender quaisquer requisitos ― Flexibilidade para atender dos projetos mais simples aos mais complexos ― Capacidade de gerenciamento remoto dos dispositivos ― Exemplo: Ajuste da taxa de amostragem de um sensor de estacionamento 13 Carriots: Plataforma • Regras de Negócio e Processamento de Eventos ― Plataforma capaz de armazenar e executar toda a lógica de negócio necessária ― Lógica de negócio escrita em Groovy ― Scripts Groovy são executados no motor e isolados através de uma abordagem if-then-else 14 Carriots: Plataforma • Exemplo de uma lógica de negócio em Groovy., que reage quando uma informação de estacionamento é recebida 15 Carriots: Plataforma • Segurança ― APIkeys para a definição de privilégios e visibilidades ― HTTPS para a criptografia das requisições e respostas à API REST ― Hash HMAC e senha pré-compartilhada para autenticação e verificação de conteúdo ― Permite a utilização de criptografica personalizada e adição de soluções de segurança adicionais 16 Carriots: Plataforma • Logs & Debug: Mensagens log, acessíveis a partir do painel de controle, e o console de debug são ferramentas para facilitar o desenvolvimento dos projetos hospedados na plataforma • Painel de Controle :O painel de controle fornece a capacidade de gerenciamento dos projetos a partir de uma interface Web • Módulo de Comunicação Externa: Envio de e-mails, SMSs, interação com sistemas externos, etc. 17 Carriots: Front End • Painel de Controle ― Primeira ferramenta utilizada para a construção de um projeto ― Fornece funcionalidades para a configuração do projeto, definição de privilégios de acesso, gerenciamento dos dados, etc. HTTPS Interface Web 19 Carriots: Front End • Dashboard & Painel de Controle ― Dashboards e paineis de controle construídos sobre a interface REST são o que os usuários finais realmente vêem ― Exemplos: mapas customizados das vagas de estacionamento disponíveis • Monitoramento ― Pooling da API REST ― Download de dados ― Gráficos personalizados ― Push de dados baseado em eventos HTTPS Interface Web 20 Carriots: Integração Externa • Sistemas de TI Externos Serviços Personalizados ― A Plataforma pode se integrar com outros sistemas ― Push/Pull de CRMs, ERPs... ― Exemplo: Zoho CRM, ArcGIS ... HTTP REST Serviços Web • Integrações já fornecidas ― ― ― ― ― Dropbox Twitter E-mails em massa SMSs Sockets HTTP API Outras 21 APIs Carriots: Aplicação no Contexto de Cidades Inteligentes • Recolhimento de lixo inteligente na cidade de Santander, ES • Sensores sem fio instalados nas lixeiras • Recuperam informações sobre o volume de lixo nas lixeiras • Enviam esses dados para a Carriots 22 Carriots: Aplicação no Contexto de Cidades Inteligentes • API REST permite receber os dados brutos • Interface Web personalizada permite analisar: ― Volume de lixo ― Estado das baterias dos sensores ― Qualidade do sinal para a transmissão de dados (GPRS) 23 Xively • Utiliza serviços de nuvem para gerenciar os dados providos pelos dispositivos • Fornece uma API RESTful para envio dos dados • Permite a visualização de dados históricos • Provê mecanismos para disparo de eventos com base nos dados gerados pelos sensores (triggers) 25 Xively: Arquitetura 26 Xively • Os dados são organizados em: ― Feeds ― Datapoints ― Datastreams • Formas de recuperação de dados: ― JSON, EEML (Extended Environments Markup Language) ou CSV através da API REST ― Através de sockets ― Protocolo MQTT • EEML permite a descrição semântica do dado coletado • Segurança ― Utilização de HTTPS ― Chave para utilização da API 27 EcoDiF • Desenvolvido no contexto do GT-EcoDiF da RNP • Integra dispositivos heterogêneos e fornece funcionalidades de controle, visualização, processamento e armazenamento de dados em tempo real. 28 EcoDiF: Arquitetura • Conexão de Dispositivos: facilita a conexão de dispositivos físicos à plataforma e, consequentemente, à Internet • Fabricantes desenvolvem drivers compatíveis com a API da EcoDiF • Usuários conectam seus dispositivos, que utilizam os drivers previamente desenvolvidos pelos fabricantes, à plataforma para permitir a comunicação e o envio de dados Colaboração Visualização e Gerenciamento Aplicações Conexão de Dispositivos Armazenamento Manipulação de Dados Serviços Comuns (segurança, transações, etc.) 29 EcoDiF: Arquitetura • Manipulação de Dados: manipula dos dados coletados dos dispositivos em tempo real • Permite a criação do conceito de feed ― Confere um contexto semântico aos metadados e aos fluxos de dados Colaboração Visualização e Gerenciamento Aplicações Conexão de Dispositivos Armazenamento Manipulação de Dados Serviços Comuns (segurança, transações, etc.) 30 EcoDiF: Arquitetura • Visualização e Gerenciamento: Fornece uma interface Web para: ― Gerenciamento dos dispositivos conectados ― Monitoramento das condições e da localização dos dispositivos ― Criação de alertas e notificações (chamados de triggers) relacionados aos ambientes sensoriados ― Visualização de dados históricos Colaboração Visualização e Gerenciamento Applications Devices Connection Storage Data Manipulation Security, Life Cycle, transactions, etc 31 EcoDiF: Arquitetura • Colaboração: Facilita a colaboração entre usuários da plataforma • Busca por dispositivos e feeds a partir de metadados (tipo, usuário, localização...) • Busca por aplicações (mashup) disponíveis Colaboração Visualização e Gerenciamento Aplicações Conexão de Dispositivos Armazenamento Manipulação de Dados Serviços Comuns (segurança, transações, etc.) 32 EcoDiF: Arquitetura • Armazenamento: consiste de dois repositórios ― SGBD para armazenamento de dados ― Armazenamento dos scripts de construção de aplicações em sistema de arquivos Colaboração Visualização e Gerenciamento Aplicações Armazenamento Manipulação de Dados Serviços Comuns (segurança, transações, etc.) 33 EcoDiF: Arquitetura • Aplicações: provê um modelo e um ambiente de programação e execução para o desenvolvimento de mashups • Modelo de programação baseado na linguagem EMML (Enterprise Mashup Markup Language) Colaboração Visualização e Gerenciamento Aplicações Armazenamento Manipulação de Dados Serviços Comuns (segurança, transações, etc.) 34 EcoDiF: Arquitetura 1 <mashup name="app" 2 xmlns="http://www.openemml.org/2009-04-15/EMMLSchema" 3 xsi:schemaLocation="http://www.openemml.org/2009-04-15/EMMLSchema… " 4 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 5 xmlns:macro="http://www.openemml.org/2009-04-15/EMMLMacro"> 6 7 <output name="result" type="document"/> 8 <variables> 9 <variable name="feed20" type="document" /> 10 <variable name="feed19" type="document" /> 11 </variables> 12 13 <directinvoke endpoint="http://localhost:8080/EcodifAPI/api/feeds/20/datastreams/20" method="GET" outputvariable="$feed20" /> 14 <directinvoke endpoint="http://localhost:8080/EcodifAPI/api/feeds/19/datastreams/19" method="GET" outputvariable="$feed19" /> 15 16 <merge inputvariables="$feed20, $feed19" outputvariable="$result" /> 17 18 </mashup> 35 EcoDiF: Arquitetura aplicações/ consumidores de feeds Servidor de Aplicações EEML Manipulação de Dados HTTP RESTEasy EEML/REST feeds/aplicações Conexão de Dispositivos OMA EMML Engine JSF Aplicações Visualização e Gerenciamento Colaboração Armazenamento Hibernate JAAS Segurança JTA Outros JMS … serviços EEML / REST / HTTP consumidores de feeds Driver Arduino Driver Android Software livre Sistema de arquivos Banco de dados relacional 36 Middleware WSO2 • Plataforma modular, corporativa, free e open-source • Fornece todas as capacidades do lado servidor (server-side) • Desenvolvido sobre a tecnologia WSO2-Carbon baseada na OSGi (Open Service Gateway Initiative)* ― Módulos compartilham o mesmo kernel • Módulos trabalham com protocolos de interoperabilidade padrão ― HTTP, MQTT, AMQP** *OSGi Alliance: http://www.osgi.org/ **Protocolo de messageria para pub/sub. http://amqp.org 38 Middleware WSO2 http://wso2.com/products/ 39 Como podemos nos beneficiar do middleware WSO2 em IoT? Mapeamento do Middleware WSO2 para instanciar uma arquitetura IoT 40 Middleware WSO2 Mapeamento para IoT 41 Estudo de Caso: Monitoramento Inteligente de uma Sala de Reuniões Agenda • Descrição do Cenário • Visão geral • Arquitetura • Ambiente de Hardware e Software utilizados • Configuração do ambiente • Implementação • Cenário em execução 50 Descrição do Cenário Controle de salas de reuniões • Integração com a agenda corporativa de reuniões • Monitorar salas de reuniões de uma empresa ou instituição com o objetivo de deixá-las preparadas para o início de uma reunião • Monitorar temperatura, iluminação • Acionar o sistema de refrigeração X minutos antes do inicio caso a temperatura do ambiente não esteja satisfatório como também ligar a iluminação • Notificar participantes do inicio de uma reunião através de SMS 51 Visão geral da aplicação 52 C Eventos http / json eventos E Rede 802.15.4 eventos Evento atuação Sensor LM335 temperatura from SensorInputEventStream[type == 'LM335' and data >= 30.0]#window.time(10 min) select correlation_sensorId as sensorId, type as type, environment as environment, "on" as action insert into SensorOutputEventStream; Evento atuação http / json E Notificação evento Notificação Lembrete da reunião Serviço Integração E Agenda Rede 802.15.4 on / off Sala reunião 53 Arquitetura de implementação 54 Mapeamento para aplicação IoT RESTful Schema 55 Arquitetura de implementação 56 Modelo de dados dos dispositivos 57 Ambiente de Hardware e Software utilizados 58 Ambiente de Hardware 59 Ambiente - Hardware • Dispositivos arduinos • 2 Uno R3 • 2 Mega 2560 • Placa Ethernet Shield • Acesso a internet via cabo 60 Ambiente - Hardware • Módulos XBee S1 ― Estabelecer uma rede sem fio entre os dispositivos • Placa XBee explorer usb • Placa XBee pro 61 Ambiente - Hardware • Cabos USB para arduino • Cabo USB mini • Fontes de alimentação ou baterias para os arduinos • Roteador 62 Ambiente – Componentes Circuito • Temperatura • Sensor LM335 • Resistor 2.2k Ohm • Potenciômetro para calibração • Atuação • Relé para acionamento de ar condicionado, iluminação, etc. 63 Ambiente de Software 64 Ambiente - Software • Arduino IDE • Programação dos arduinos • XCTU IDE • Configuração dos módulos XBee • Ambiente Java • Java SDK 65 Ambiente - Software • Eclipse Java EE IDE for Web Developers • Plataforma WSO2 • CEP – Complex Event Processor • MB – Message Broker • SGBD MYSQL 66 Configuração do ambiente Circuito, Rede XBee, WSO2 67 Configuração do ambiente Circuito 68 Montagem do circuito de temperatura 69 Configuração do ambiente Rede XBee 70 Rede XBee Rede 802.15.4 Dispositivo final Dispositivo final Controlador da rede Dispositivo final 71 Configuração do Módulo XBee • CH : Canal • PAN-ID : ID da rede (Personal Area Network) • DH e DL : Endereço do dispositivo destino • MY : Endereço de 16 bits do dispositivo • CE : Habilitar coordenador ou disp. final • NI : Identificação do Nó • AP : Habilitar uso da API 72 Configuração do Controlador • CH : 0C • PAN-ID : 3332 • DH e DL : 0 • MY : 1001 • CE : Coordinator [1] • NI : coord_xbee • AP : API enabled w/PPP [2] 73 Configuração do Dispositivo final • CH : 0C • PAN-ID : 3332 • DH e DL : 0 • MY : 1002 • CE : End device [2] • NI : end_device_1002 • AP : API enabled w/PPP [2] 74 Configuração do Módulo XBee • Conectar o Módulo XBee no explorer • Abrir o programa XTCU • Clicar na opção Discover devices 75 Configuração do Módulo XBee 76 Configuração do Módulo XBee • Janela apresenta uma lista com os dispositivos encontrados • Selecionamos os dispositivos e clicamos no botão Add selected devices 77 Configuração do Módulo XBee • Configuração dos parâmetros do módulo 78 Configuração do Módulo XBee • Configuração dos parametros do módulo • Após configurar os parametros, salvar as configurações no módulo usando o menu ao lado 79 WSO2-CEP 80 WSO2 – CEP – O que processar? • Processar eventos de temperatura de um determinado ambiente coletados através de um sensor do tipo LM335 e transmitidos ao CEP por um determinado dispositivo. • Os eventos com temperatura serão acumulados a cada 5 minutos para processamento em modo batch e um dispositivo de atuação será selecionado para envio do comando de atuação. 81 WSO2 – CEP – O que processar? • Caso o total dos eventos de temperaturas acima ou igual a 25 graus seja maior ou igual a 30, uma mensagem de atuação com o comando “ON” será enviado. • Caso o total dos eventos de temperaturas abaixo de 25 graus seja maior ou igual a 30, uma mensagem de atuação com o comando “OFF” será enviado. • Notificar participantes sobre o início da reunião 82 WSO2 Criar fluxo de eventos e plano de execução para o evento de temperatura 83 WSO2 – CEP - Eventos • Os passos para criar um fluxo de eventos são: 1. Receber (I) e transmitir (O) eventos via HTTP 2. Eventos (I-O) estão em formato JSON 3. Transformar eventos 1. JSON -> WSO2Event -> JSON 4. Criar plano de execução • Os passos de 1 a 3 são genéricos porque a aplicação envia mensagens padronizadas de sensoriamento independente do tipo de sensor utilizado. O passo 4 é dependente da condição de atuação desejada. 84 WSO2 - CEP • Iniciar o servidor • Abrir o navegador e entrar no gerenciador • URL: https://localhost:9443/ carbon • Login/Senha: admin/admin 85 WSO2 - CEP • Criar os Input/Output adaptors • Utilizados para receber eventos de uma fonte e publicar eventos para um coletor • Clicar na pasta Configure e ir na opção Event Processor Configs 86 WSO2 – CEP – Input adaptor • Criar um Input adaptor • Clicar na opção Input Event Adaptors • Clicar na opção Add Input Event Adaptor 87 WSO2 – CEP – Input adaptor • Fazer a configuração adequada para o tipo de fonte dos eventos. 88 WSO2 – CEP – Output adaptor • Criar um Output adaptor • Clicar na opção Output Event Adaptors • Clicar na opção Add Output Event Adaptor 89 WSO2 – CEP – Output adaptor • Fazer a configuração adequada para o tipo de coletor dos eventos. 90 WSO2 – CEP – Event Streams • 1-Clicar na aba Main • 2-Selecionar Event Streams • 3-Clicar em Add Event Stream 1 3 2 91 WSO2 – CEP – Novo Event Stream • Etapa 1 de 2 – Dados básicos • * campos obrigatórios 92 WSO2 – CEP – Novo Event Stream • Etapa 2 de 2 • Definir a estrutura do evento, configurando o nome dos atributos e seu tipo • No final clicar em Add Event Stream e será exibido uma janela solicitando a definição de um EventBuilder 93 WSO2 – CEP – Novo Event Stream • Janela solicitando a definição de um EventBuilder • Clicar no botão Create Later • Repetir os passos 1 e 2 para criar todos os Event Stream 94 WSO2 – CEP – definir Event Builder e Formatters • Definição de um Event Builder para receber eventos externos via http • Mapeamento do evento de entrada para o formato interno do CEP • Clicar na opção In-Flows para definir 95 WSO2 – CEP – definir Event Builder • Definição de um In-Flow • Clicar em (+) Receive from... 96 WSO2 – CEP – definir Event Builder • Definição em 2 passos • Passo 1 de 2 – Definir Event Builder Name, Input, Topic e Mapping type 1 2 3 4 97 WSO2 – CEP – definir Event Builder • Passo 2 de 2 –clicar no (+) Advanced para configurar o path de mapeamento de cada campo e no final clicar em Add Event Builder. 98 WSO2 – CEP – definir Event Builder • Após realizar a configuração o CEP exporta uma URL para envio de eventos • Método: POST • http://localhost:9763/endpoints/httpInputSen sor/SensorBuilder 99 WSO2 – CEP – definir Formatters • Event Formatters é responsável pelo mapeamento de saída • Converter um evento (WSO2Event) em diferentes formatos (XML, MAP, JSON e Text) • Clicar na opção Out-Flows para definir 100 WSO2 – CEP – definir Formatters • Definição de um Out-Flow • Clicar em (+) Publish to External... 101 WSO2 – CEP – definir Formatters • Definição em 2 passos • Passo 1 de 2 – Definir o Formatter Name e Output Adaptor 102 WSO2 – CEP – definir Formatters • Passo 1 de 2 – configuração da URL que receberá o evento de saída 103 WSO2 – CEP – definir Formatters • Passo 2 de 2 – configuração do evento de saída • Indicar o tipo de evento, o conteúdo do evento e no final clicar em Add... 104 WSO2 – CEP – definir Data source • Acesso ao modelo de dados do Gerenciador de Dispositivo para selecionar o dispositivo “atuador”. • 1 – clicar na aba Configure • 2 – clicar na opção Data Sources • 3 – clicar em (+) Add Data Source 1 2 3 105 WSO2 – CEP – definir Data source • Configurar os campos com * 106 Plano de Execução 107 WSO2 – CEP – Plano de Execução • Processa os eventos de entrada e gerar eventos de saída • Programado através de uma linguagem baseada em SQL • 1 - Clicar na aba Main • 2 - Selecionar Execution Plans • 3 - Selecionar (+) Add Execution Plan 1 2 3 108 WSO2 – CEP – Plano de Execução • Definição em 3 passos • Passo 1 – Definir o Execution Plan Name 109 WSO2 – CEP – Plano de Execução • Passo 2 – Definir os Streams de Input e Output do SQL • Definição do Import Stream • 1 - Selecionar o Input Stream definido e indicas um alias (AS) • 2 - Clicar em Import 2 1 110 WSO2 – CEP – Plano de Execução • Definição do Export Stream • 1 - Indicar um Value Of • 2 - Selecionar o Output Stream definido • 3 - Clicar em Add 1 3 2 111 WSO2 – CEP – Plano de Execução • Passo 3 – Definição do SQL 112 WSO2 – CEP – Plano de Execução • SQL define table actuator (id int, macAddress string, env string, sensorType string) from ('datasource.name'='SensorDS', 'table.name'='actuator'); from SensorInputEventStream [si.type == 'LM335' and si.data >= 25.0]#window.timeBatch(5 min) as si join actuator as a on (si.type == a.sensorType) and (a.env == si.environment) select a.macAddress as sensorId, si.type as type, si.environment as environment, "on" as action, count(*) as qtd group by si.correlation_sensorId, a.macAddress having qtd>=30 insert into SensorOutputEventStream2; 113 WSO2 – CEP – Fluxo de eventos • Visualização do fluxo do evento • 1 – Clicar na Aba Monitor • 2 – Clicar na opção Event Flow 1 2 114 WSO2 – CEP – Fluxo de eventos • Integração com a Agenda Corporativa • Mesmos passos indicados anteriormente • Pontos de atenção • O Input adapter será do tipo JMS • Na criação do EventBuilder (In-Flow) deve-se configurar o topic/queue que a aplicação da agenda esta publicando as mensagens • O Output adaptor será do tipo SMS 115 WSO2 – CEP • Input Adapter usando JMS 116 WSO2 – CEP • Event Builder 117 Implementação Arduinos e API Rest 118 Arduinos 119 Arduinos • Linguagem de programação baseada em C • Dividida em 4 módulos: • Coletor de dados dos sensores • Coordenador de Recebimento de eventos e envio ao CEP • Coordenador de atuação • Recebimento de evento do CEP e envio para atuação • Atuador 120 Arduinos • Bibliotecas • Arduino JSON • XBee • Ethernet 121 Coletor de dados de sensor 122 Arduinos – Coletor de dados de sensor • Dispositivo resposável por • Requisitar informações sobre ambiente a sensoriar • coletar dados dos sensores • formatar a mensagem (JSON) • enviar ao Coordenador 123 Arduinos – Coletor de dados de sensor • setup do dispositivo void setup() { pinMode(LEDVerde, OUTPUT); pinMode(LEDVermelho, OUTPUT); pinMode(LEDAmarelo, OUTPUT); pinMode(13, OUTPUT); Serial.begin(9600); xbee.setSerial(Serial); initVars(); tentativas = 0; } 124 Arduinos – Coletor de dados de sensor • setup do dispositivo void initVars() { macAddr = getMAC(); type = "LM335"; env = "SL102"; measure = "C"; pin = 0; tpin = "A"; } String getMAC() { uint8_t shCmd[] = {'S', 'H'}; uint8_t slCmd[] = {'S', 'L'}; String mac = getResultRequest(shCmd); delay(50); mac.concat(getResultRequest(slCmd)); mac.toUpperCase(); return mac; } 125 Arduinos – Coletor de dados de sensor • loop de execução void loop() { if (tentativas > -1) { initMessage(); // gera msg de config ao coordenador if (tentativas > 10) { tentativas = -1; } return; } [...] } 126 Arduinos – Coletor de dados de sensor • Solicita configuração • Mensagem: {“start”: ”0013A2004076DAF9”} void initMessage() { String cmd = "{\"start\":\""; cmd.concat(macAddr + "\"}"); [...] uint8_t * payload = (uint8_t *) msg; Tx64Request tx = Tx64Request(addr64, payload, msgsize); [....] // enviar a mensagem p/ coordenador xbee.send(tx); [...] } 127 Arduinos – Coletor de dados de sensor • Recebe e processa a configuração void initMessage() { [...] xbee.readPacket(5000); if (xbee.getResponse().isAvailable()) { [...] if (xbee.getResponse().getApiId() == RX_16_RESPONSE) { xbee.getResponse().getRx16Response(rx16); rxData = rx16.getData(); offset = rx16.getDataOffset(); lenData = rx16.getDataLength(); } else { [...] } // se chegou a resposta da mensagem de inicialização interrompe processConfigMessage(); tentativas = -1; } [...] 128 Arduinos – Coletor de dados de sensor • Processa a mensagem de configuração recebida • {"id":"0013A2004076DAF9","type":"LM335","env":"SL102","pin":0,"tpin":"A"," measure":"C"} void processConfigMessage() { String json = dataToString(rxData, 0, lenData); int jsonLen = json.length() + 1; char * msg = (char *) malloc( sizeof( int ) * jsonLen); json.toCharArray(msg, jsonLen); DynamicJsonBuffer jsonBuffer; JsonObject& root = jsonBuffer.parseObject(msg); type = root["type"]; env = root["env"]; measure = root["measure"]; pin = root["pin"]; tpin = root["tpin"]; free(msg); } 129 Arduinos – Coletor de dados de sensor • Coleta dados do sensor e formata mensagem para envio • Exemplo: {"id":"0013A2004076DAF9","type":"LM335","env":"SL102","data":0.0,"measu re":"C"} // envia a mensagem formatada void sendMessage() { float data = getTemperature(); char * json = getJson(macAddr, type, env, data, measure); int jsonsize = strlen(json); uint8_t * payload = (uint8_t *) json; Tx64Request tx = Tx64Request(addr64, payload, jsonsize); // envia a mensagem para o coordenador xbee.send(tx); } 130 Arduinos – Coletor de dados de sensor • Coleta dados do sensor float getTemperature() { float setting = 2.5; float sensorValue = 0; if (tpin == "A") { sensorValue = analogRead(pin); } else { [...] } float kelvin = (((sensorValue / 1023) * 5) * 100); float celsius = kelvin - 273.15 - setting; return celsius; // Retorna A temperatura } 131 Coordenador de recebimento de eventos 132 Arduinos – Coordenador de recebimento de eventos • Dispositivo resposável por • Receber a mensagem de config do dispositivo, interagir com o sistema de gerenciamento de dispositivos, via API REST, e devolver configuração • Receber os eventos coletados dos sensores • Formatar uma nova mensagem (JSON) no modelo do CEP • Enviar mensagem ao CEP 133 Arduinos – Coordenador de recebimento de eventos • Código de setup void setup() { [...] Serial.begin(9600); xbee.setSerial(Serial); digitalWrite(statusLed, HIGH); Serial.println("Obtendo IP via DHCP..."); if (Ethernet.begin(mac) != 1) { flashLed(errorLed, 2, 100); Ethernet.begin(mac, ip); } digitalWrite(statusLed, LOW); Serial.print("IP Client : "); Serial.println(Ethernet.localIP()); IPok = 1; flashLed(greenLed, 3, 100); } 134 Arduinos – Coordenador de recebimento de eventos • Código de processamento void loop() { if (IPok == 1) { if (readSensorPacket() == 1) { verifyMessageAndSendMessage(); } delay(50); } } 135 Arduinos – Coordenador de recebimento de eventos • Código de tratamento de mensagens recebidas void verifyMessageAndSendMessage() { String msg = dataToString(rxData, 0, lenData); Serial.println("Mensagem ->"+msg); String mac = getMacAddressFromStartMessage(msg); // verifica se é mensagem de inicialização do device if (mac.length() > 0) { Serial.println("Recebida mensagem de Config."); sendMessageConfig(mac); } else { Serial.println("Recebida mensagem de sensor."); sendDataCEP(msg); } free(jsonArray); } 136 Arduinos – Coordenador de recebimento de eventos • Código de envio de mensagens de config ao dispositivo void sendMessageConfig(String mac) { String jsonConfig = getDeviceConfig(mac); if (jsonConfig.length() > 0) { sendMessageDevice(jsonConfig); } } String getDeviceConfig(String mac) { String body = ""; httpRequest("192.168.1.112", 8080, "/devicemanager/device/sensoring/" + mac); [...] body = parseBody(body); } else { Serial.println("Sem retorno"); } body.trim(); return body; } 137 Arduinos – Coordenador de recebimento de eventos • Buscar config no Gerenciador de Dispositivos void httpRequest(const char * server, unsigned long port, String url) { if (client.connect(server, port)) { client.println("GET " + url + " HTTP/1.1"); client.println("Host: " + String(server) + ":" + String(port)); client.println("User-Agent: arduino-ethernet"); client.println("Content-Type: application/json"); client.println("Cache-Control: no-cache"); client.println("Connection: close"); client.println(); delay(50); } else { Serial.println("connection failed"); } } 138 Arduinos – Coordenador de recebimento de eventos • Enviar configuração ao dispositivo void sendMessageDevice(String msg) { // Parse da mensagem JSON recebida do DM [...] msg.toCharArray(msgArray, msgsize); DynamicJsonBuffer jsonBuffer; JsonObject& root = jsonBuffer.parseObject(msgArray); [...] const char* env = root["sala"]; const char* sensortype = root["sensortype"]; const int pin = root["pin"]; [...] //formata a msg de resposta a solicitação do device char * json = getJSONConfig(macaddress, sensortype, env, measure, pin, tpin); uint8_t * payload = (uint8_t *) json; Tx64Request tx = Tx64Request(addr64, payload, strlen(json)); xbee.send(tx); [...] } 139 Arduinos – Coordenador de recebimento de eventos • Código de envio de mensagens para o WSO2-CEP void sendDataCEP(String msg) { httpRequest("192.168.1.112", 9763, "/endpoints/httpInputSensor/SensorBuilder", getDataToCEP(msg) ); } 140 Arduinos – Coordenador de recebimento de eventos • Código de envio de mensagens para o WSO2-CEP • Formato mapeado no Event Builder: {"id":"0013A2004076DAF9","type":"LM335","env":"SL102","data":28.00,"measure":"C"} char * getDataToCEP(String json) { [...] int jsonLen = json.length() + 1; // parser do evento recebido do dispositivo [...] JsonObject& root = jsonBuffer.parseObject(jsonArray); [...] const char* sensorId = root["id"]; const char* type = root["type"]; [...] return getJSON(sensorId, type, date, time, env, data, measurement); } 141 Arduinos – Coordenador de recebimento de eventos • Código de envio de mensagens para o CEP void httpRequest(const char * server, unsigned long port, char * url, char * data) { [...] if (client.connect(server, port)) { String host = String (server); String sensorData = String (data); // Make a HTTP request: client.println("POST " + (String)url + " HTTP/1.1"); client.println("Host: " + host); client.println("User-Agent: arduino-ethernet"); client.println("Content-type: application/json"); client.println("Connection: close"); client.println("Content-length: " + (String)strlen(data) + "\n"); client.println(sensorData); client.println(); delay(50); } [...] 142 Coordenador de atuação 143 Arduinos – Coordenador de atuação • Dispositivo resposável por • É iniciado como um servidor WEB e disponibiliza uma API • Recebe a mensagem de atuação via HTTP • do servidor CEP ou de qualquer aplicativo • Identifica o dispositivo de atuação • Envia mensagem de atuação 144 Arduinos – Coordenador de atuação • Código de setup […] // MAC address byte mac[] = { 0x90, 0xA2, 0xDA, 0x03, 0x00, 0xA2 }; IPAddress ip(192, 168, 1, 163); void setup() { [...] Serial.begin(9600); // iniciar uma conexão Ethernet digitalWrite(statusLed, HIGH); Ethernet.begin(mac, ip); server.begin(); digitalWrite(statusLed, LOW); // Inicializa o Ethernet server library EthernetServer server(80); Serial.print("Server ON no IP : "); Serial.println(Ethernet.localIP()); […] } 145 Arduinos – Coordenador de atuação • Processamento de mensagens recebidas void loop() { // escutar as mensagens HTTP vindas dos clientes EthernetClient client = server.available(); String body = ""; if (client) { while (client.connected()) { if (client.available()) { // mensagem HTTP disponível char c = client.read(); body.concat(c); } else { break; } } } ... 146 Arduinos – Coordenador de atuação • Processamento de mensagens recebidas ... digitalWrite(statusLed, HIGH); // envia mensagem de Ok para o cliente sendAnswer(client); delay(10); digitalWrite(statusLed, LOW); client.stop(); // envia a mensagem de atuação sendMessage ( parseBody(body) ); } 147 Arduinos – Coordenador de atuação • Envia uma resposta ao cliente de mensagem recebida void sendAnswer(EthernetClient client) { client.println("HTTP/1.1 200 OK"); client.println("Content-Type: application/json"); client.println("Connection: close"); client.println(); client.println("{\"status\":\"OK\"}"); } 148 Arduinos – Coordenador de atuação • Forma a mensagem e envia ao dispositivo de atuação void sendMessage(String msg) { [...] int msgsize = msg.length()+1; char * msgArray = (char *) malloc( sizeof( int ) * msgsize); msg.toCharArray(msgArray, msgsize); DynamicJsonBuffer jsonBuffer; JsonObject& root = jsonBuffer.parseObject(msgArray); const char* sensorId = root["sensorId"]; const char* type = root["type"]; const char* environment = root["environment"]; const char* action = root["action"]; .... 149 Arduinos – Coordenador de atuação • continuação ... char macHigh[9], macLow[9]; strncpy(macHigh, sensorId, 8);macHigh[8]='\0'; strncpy(macLow, sensorId+8, 8);macLow[8]='\0'; // uint32_t msb = strtoul(macHigh, 0, 16); uint32_t lsb = strtoul(macLow, 0, 16); //Seta o mac address do dispositivo de atuação addr64.setMsb (msb); addr64.setLsb (lsb); uint8_t * payload = (uint8_t *) action; Tx64Request tx = Tx64Request(addr64, payload, strlen(action)); xbee.send(tx); [...] } 150 Atuador 151 Arduinos – Atuador • Dispositivo resposável por • Receber a mensagem de atuação do coordenador e ativar o dispositivo associado por exemplo: um ar-condicionado, um luminária, um eletrodomêstico, etc... 152 Arduinos – Atuador • Código de setup void setup() { pinMode(statusLed, OUTPUT); pinMode(redLed, OUTPUT); pinMode(greenLed, OUTPUT); pinMode(dispositivo, OUTPUT); // start serial Serial.begin(9600); xbee.setSerial(Serial); flashLed(statusLed, 3, 50); } 153 Arduinos – Atuador • Código de recebimento de comando de atuação void loop() { xbee.readPacket(5000); if (xbee.getResponse().isAvailable()) { [...] if (xbee.getResponse().getApiId() == RX_16_RESPONSE) { xbee.getResponse().getRx16Response(rx16); rxData = rx16.getData(); offset = rx16.getDataOffset(); lenData = rx16.getDataLength(); } else { [...] } doActuation(); [...] } 154 Arduinos – Atuador • Código de atuação void doActuation() { String msg = dataToString(rxData, 0, lenData); msg.toUpperCase(); if (msg == "ON") { digitalWrite(dispositivo, HIGH); } else { digitalWrite(dispositivo, LOW); } } 155 API REST Gerenciar dispositivos 156 API REST - Gerenciar dispositivos @RequestMapping(method = RequestMethod.GET, value = "/device/sensoring/{macAddress}") @ResponseBody public Object getDeviceMonitor(@PathVariable String macAddress) throws Exception { try { return dmService.getDeviceMonitor(macAddress); } catch (Exception e) { throw new Exception("Ocorreu um erro ao processar dados! Erro="+e.getMessage()); } } 157 Aplicação na prática 158 Plataformas para a Internet das Coisas Paulo F. Pires1, Flavia C. Delicato1, Thais Batista2, Thomaz Barros1, Everton Cavalcante1,3, Marcelo Pitanga1 1DCC/PPGI, Universidade Federal do Rio de Janeiro, Rio de Janeiro, Brasil 2DIMAp, Universidade Federal do Rio Grande do Norte, Natal, Brasil 3IRISA-UMR CNRS/Université de Bretagne-Sud, Vannes, França