Azure Insider

Soup to Nuts: De hardware bruto a um dispositivo habilitado para nuvem

Bruno Terkaly
Steven Edouard

Bruno Terkaly and Ricardo VillalobosHá uma nova corrida do ouro acontecendo e não está relacionada aos metais preciosos. Está relacionada ao desenvolvimento de dispositivos inovadores para consumidores e com a sua conexão à nuvem. O novo CEO da Microsoft Satya Nadella disse em março passado que os dispositivos “realmente não são interessantes sem a nuvem”.

Faz sentido. Se o dispositivo está coletando informações por meio de sensores ou câmeras, como e onde você analisará estes dados? Afinal, esses dispositivos mais básicos, como o Raspberry Pi têm poder de computação e espaço de armazenamento limitados. A nuvem preenche esse vazio e vai além ao ajudar na segurança, gerenciamento do dispositivo e assim por diante. Então este mês, queremos arregaçar nossas mangas na perspectiva de hardware e software e descobrir o que é necessário para verdadeiramente adotar esse novo paradigma informático.

O SmartDoor é o produto da Internet das Coisas (IoT) que desenvolveremos do zero. Eventualmente anexaremos uma campainha, uma câmera e um dispositivo de computação Raspberry Pi (veja a Figura 1). A ideia é que alguém chegue na sua entrada e toque a sua campainha. Quando eles pressionam a campainha, o dispositivo tira uma foto automaticamente. Em seguida, essa foto é encaminhada para um dispositivo móvel como uma mensagem de notificação por push (veja a Figura 2). A mensagem tem um hiperlink para a imagem da pessoa que está na sua porta. Essa invenção foi inspirada pela necessidade de saber quem está tocando sua campainha, mesmo que você não esteja em casa.

Esse projeto combina uma campainha, câmera e um dispositivo Raspberry Pi
Figura 1 Esse projeto combina uma campainha, câmera e um dispositivo Raspberry Pi

O Windows Phone recebendo a notificação por push
Figura 2 O Windows Phone recebendo a notificação por push

Começaremos ilustrando exatamente como comprar e montar o hardware bruto. Após desenvolver o hardware, desenvolveremos o software que executa no próprio dispositivo, bem como o software que está executando no Microsoft Azure. No entanto, este e artigos futuros se concentrarão principalmente no software obrigatório.

Precisaremos do código para poder tirar uma foto e carregá-la para o Azure. A partir daí, será necessário enviar uma notificação por push para os dispositivos móveis apropriados. Isso indicará que alguém tocou na campainha e uma foto daquela pessoa estará disponível. Devido a natureza ambiciosa desse projeto, forneceremos várias postagens de blog para dar suporte ao trabalho e forneceremos os detalhes necessários.

Fácil como o Pi

Abordaremos o código que é executado no próprio dispositivo Raspberry Pi e alguns dos código que executarão na nuvem—especificamente dentro do Serviços móveis do Azure. No Raspberry Pi, instalaremos e executaremos o Mono, que é um projeto gratuito, código aberto liderado por Xamarin que fornece um conjunto de ferramentas compatível com o Microsoft .NET Framework incluindo um compilador C# e um CLR. 

A vantagem do Mono é que ele deixa você escrever o código .NET compilado no Windows e executa-o inalterado no Raspberry Pi. No nosso caso, tiraremos a foto e carregaremos ela no armazenamento do Azure. Em artigos futuros, expandiremos a base de código para dar suporte à capacidade de enviar notificações por push para um Windows Phone. Para fazer isso, teremos que aproveitar as notificações por push no Barramento de Serviço do Azure e escrever um aplicativo do Windows Phone ou Windows Store.

Reunir o hardware é fácil, pois todo hardware está disponível em um único kit do Raspberry Pi chamado de Canakit. Para obter mais detalhes, acesso o canakit.com. O kit contém algumas coisas úteis para o desenvolvimento do nosso dispositivo IoT, incluindo uma placa do sistema, adaptador C/A, circuito de entrada/saída GPIO para uso geral, placa universal, cabos da placa universal, resistores variados e LEDs. Você também precisará de um monitor externo, teclado e mouse para poder configurar e testar o Raspberry Pi. Além do Canakit, será necessário mais duas coisas—uma campainha comum e uma câmera compatível com o Raspberry Pi, que são fáceis de encontrar.

Embora a pilha de hardware na Figura 3 talvez pareça assustadora, é na verdade bem simples para juntar. Se você puder montar um quebra-cabeça, será possível desenvolver um dispositivo como o SmartDoor. Primeiro, conecte o módulo da câmera na placa do Raspberry Pi. Retire a câmera da bolsa e conecte o cabo flexível à placa do Raspberry Pi. Acesse bit.ly/1rk3vzk para obter mais detalhes sobre enviar fotos para a nuvem.

O Canakit do Raspberry Pi (Não inclui a câmera)
Figura 3 O Canakit do Raspberry Pi (Não inclui a câmera)

Apresentaremos a instalação completa da própria campainha em um artigo posterior, onde iremos unificá-lo ao Raspberry Pi. Por enquanto, conectaremos uma placa universal, que é uma versão de avaliação de um circuito elétrico conectado ao Raspberry Pi. Podemos usar cabos auxiliares e a placa universal para simular a campainha.

Um dos componentes principais é a placa universal GPIO. O GPIO é um circuito de hardware com 26 pinos separados (numerados da esquerda para direita) que permite que você expanda o sistema para interagir com outros dispositivos. Geralmente, esses pinos permitem que você conecte coisas como sensores, atuadores, LEDs e assim por diante. No entanto, há vários tipos de pinos. Por exemplo, há dois pinos fornecendo uma fonte da alimentação para dispositivos conectados, especificamente um de 3,3 volt e um de 5 volt. Há também um pino de 0 volt que funciona como um terra, que é necessário para definir um circuito. Os pinos rotulados GPIO funcionam como um interruptor ligar/desligar simples. Se desejar realizar comunicações em série, você encontrará pinos TX e RX (RS-232) para transmitir e receber dados. O software que executa no dispositivo precisará se comunicar com esses pinos.

Uma das complexidades de lidar com esses pinos é que há uma divergência entre os pinos físicos e os pinos lógicos com o qual o software se comunica. Isso tem a ver com os chips Broadcom no dispositivo Raspberry Pi. Isso significa se um sinal vai para o pino GPIO 0, seu software, na verdade, precisa ler pino GPIO 17. Pode não ser lógico, então tenha cuidado.

Há outros componentes de hardware importantes. Os resistores desempenham um papel importante ao controlar o fluxo da corrente e ao baixar os níveis da voltagem, assim você não frita o Raspberry Pi ou qualquer outro dispositivo conectado a ele. Você também precisará de um cabo de núcleo único para conectar à unidade do GPIO ao Raspberry PI.

Testando, testando

Consequentemente, precisaremos verificar se desenvolvemos o hardware corretamente. A maneira mais fácil de testar o Raspberry Pi é simplesmente conectar o monitor externo, teclado, mouse opcional e fonte de alimentação. Quando estiver pronto, conecte na energia e a sequência de inicialização para o Linux deve aparecer. O nome de usuário padrão será “pi” e a senha será “raspberry”. Acesse o bit.ly/1k8xBFn para obter mais detalhes sobre como configurar um Raspberry Pi.

O Raspberry Pi precisa de software adicional, como o Mono para poder executar o código C#. Antes de podermos fazer algo no dispositivo, precisamos atualizar seu sistema operacional Raspbian. Felizmente, o Pi vem com uma versão pré-instalada. Tudo que precisamos fazer é emitir alguns comandos em uma janela do console para atualizar o sistema operacional com a revisão mais recente. Depois podemos instalar o tempo de execução Mono do Xamarin e alguns certificados raiz confiáveis. Eles permitirão que o dispositivo faça solicitações HTTPS. Todas essas etapas são explicadas na postagem do blog em bit.ly/Unehrr.

O lado do software

Há duas camadas que precisamos codificar, a camada do cliente (o próprio dispositivo Raspberry Pi) e a camada de serviço (Armazenamento do Azure e Serviços Móveis do Azure). Há uma variedade de linguagens e serviços back-end para escolher. Executaremos o C# no cliente e Node.js/JavaScript no servidor. Essa pode ser uma escolha controversa, pois algumas pessoas acham que duas linguagens diferentes complicam a implementação.

Nosso objetivo foi mostrar diversidade. No contexto do Node.js, acreditamos que várias bibliotecas e pacotes encontrados em npmjs.org poderiam potencialmente tornar o seu código de servidor muito mais fácil. O Node.js geralmente resulta em uma base de código muito menor porque as bibliotecas são tão poderosas. Menos códigos em uma segunda linguagem é melhor do que vários códigos na mesma linguagem. O diagrama na Figura 4 destaca o fluxo de trabalho esperado, que se resume em três etapas:

  1. O cliente solicita um token de Assinatura de acesso compartilhado (SAS), que é apresentado com uma URL.
  2. O aplicativo Node.js que está executando dentro dos Serviços Móveis do Azure retornará uma URL SAS.
  3. O cliente usará a URL SAS para carregar a foto para o Armazenamento do Azure como um blob.

Diagrama arquitetural de nível superior do projeto SmartDoor
Figura 4 Diagrama arquitetural de nível superior do projeto SmartDoor

Hospedamos nosso aplicativo Node.js dentro dos Serviços Móveis do Azure. Isso fornece bastante suporte pré-integrado para clientes de dispositivo móvel, como notificações por push, integração de armazenamento de CRUD, identidade e a capacidade de criar uma API personalizada.

Foco no serviço

Começaremos criando nosso serviço, pois ele desenvolverá o cliente se não houver camada de serviço para codificar. Não haveria nenhuma forma de realmente executar e testar o cliente, a menos que você tenha um serviço back-end totalmente funcional. Os Serviços Móveis do Azure hospedarão nossa API de serviço.

Essa API personalizada estará baseada na estrutura Node.js e Express Web. Nosso cliente (Raspberry Pi) usará esses serviços para solicitar uma SAS. Depois o serviço usará aquele token para carregar a foto que ele tira para o Armazenamento do Azure. Usar um URL SAS ajuda a proteger nossa conta do Armazenamento do Azure, pois não precisaremos armazenar as credenciais da conta no Raspberry Pi. 

Nós abordamos problemas de segurança adicionais em artigos passados (msdn.microsoft.com/magazine/dn574801). Os tokens SAS são também bons por outro motivo—eles isentam a camada intermediária (Node.js API) de precisar intermediar a transferência de arquivos para o armazenamento do cliente.

Provisionamento móvel e armazenamento

O provisionamento dos Serviços Móveis do Azure consiste de apenas alguns cliques no portal do Azure. O mesmo é verdadeiro para o provisionamento do Armazenamento do Azure. Como com qualquer coisa que é provisionada, você precisará pensar sobre as URLs e as convenções de nomenclatura que deseja utilizar para seus serviços baseados na nuvem. Você também deve considerar quais os vários datacenters globais deseja utilizar, certificando-se de que sua conta de armazenamento está no mesmo datacenter que os Serviços Móveis do Azure, para minimizar a latência e evitar custos de transferência de dados. Você pode encontrar etapas mais detalhadas para o provisionamento da sua conta dos Serviços Móveis do Azure e do Armazenamento do Azure em bit.ly/WyQird.

Assinaturas de acesso compartilhado

Como mostrado na Figura 4, o cliente do Raspberry Pi solicitará um token SAS dos Serviços móveis do Azure. Isso será feito ao emitir um solicitação get de uma API que definimos dentro dos Serviços Móveis do Azure. Os tokens SAS isentam a camada intermediária (Node.js API) de precisar intermediar a transferência de arquivos para o armazenamento do cliente.

O código na Figura 5 é um trecho do Node.js que está executando dentro dos Serviços Móveis do Azure como um ponto de extremidade do serviço da API. O objetivo é responder às solicitações dos clientes do Raspberry Pi que precisam de uma SAS. O Raspberry Pi emitirá uma solicitação “get” para o ponto de extremidade hospedado nos Serviços Móveis do Azure, passando a chave de aplicativo, que um identificador que representa exclusivamente nosso serviço móvel.

Figura 5 O código Node.js para a API dos Serviços Móveis do Microsoft Azure

exports.get = function(request, response) {
  // These are part of "App Settings" in the configuration section
  // of your service. Shouldn't be hardcoded into this Node.js script.
  containerName = request.service.config.appSettings.PhotoContainerName;
    accountName = request.service.config.appSettings.AccountName;
    accountKey = request.service.config.appSettings.AccountKey;
  // Connect to the Blob service.
  blobService = azure.createBlobService(
    accountName,accountKey,accountName + '.blob.core.windows.net');
  createContainer();
  createPolicies();
  var sasResponse = GetSAS();
  return request.respond(201, sasResponse);
}

A chave de aplicativo representa uma forma segura de se comunicar com o Serviço Móvel do Azure específico. O serviço obterá essa chave do portal, que o código que está executando no Raspberry Pi utilizará, portanto, você deve mantê-la acessível. Depois você pode colar a chave no código do cliente. O cliente recebe uma SAS encapsulada dentro de uma URL que o cliente pode usar em uma operação posterior para carregar a foto.

Agora nos concentraremos em alguns dos códigos que representam o aplicativo Node.js do lado do servidor. Há um SDK Node.js poderoso para o Azure disponível em bit.ly/Unnikj. Essa base de código fornece bastante suporte para outras partes da plataforma do Azure, como trabalhar com tabelas, filas, tópicos, hubs de notificação, gerenciamento principal e assim por diante. Você pode encontrar um tutorial sobre a integração do Node.js e do Armazenamento de Blob no Azure em bit.ly/1nBEvBa.

Para nossos objetivos, a SAS que o aplicativo Node.JS retorna para o cliente está ligada a conta de armazenamento que provisionamos anteriormente. Como tal, o aplicativo Node.js precisará do nome da conta da conta de armazenamento e da chave de gerenciamento.

Os Serviços Móveis do Azure permitem que você externalize as definições de configuração do seu aplicativo Node.js. É geralmente considerada uma prática de programação ruim codificar as configurações da chave da conta diretamente em código. As configurações do aplicativo permitem que você defina os pares valor-chave que o tempo de execução do serviço possa ler. Você pode saber mais sobre isso em bit.ly/1pwGFRN.

Finalmente, o código Node.js retornará uma URL com a SAS que o cliente pode utilizar para carregar as fotos. Juntamente com o token SAS, o aplicativo Node.js retorna um status HTTP de 201. Isso significa que ele atendeu a solicitação e criou um novo recurso (o token SAS).

Você encontrará uma instrução mais detalhada que aborda o Node.js, a URL SAS e as configuração de aplicativo em bit.ly/WyQird.

Dentro do código do Raspberry Pi

A interface de hardware/software é na verdade bastante direta. Você pode pensar sobre o código do lado do cliente como uma máquina de estado gigante. Ela está em um loop constante verificando o status dos pinos GPIO. Como você pode ver pelo código na Figura 6, estamos apenas verificando para ver se um pino está ativado ou desativado, true ou false.

Figura 6 Loop de sondagem longo fazendo interface com o GPIO do Raspberry Pi para controlar o comportamento

while (true)
{
  // If pin 17 is off, we are ready.
  if (!s_Gpio.InputPin(FileGPIO.FileGPIO.enumPIN.gpio17))
  {
    showReady(true);
    // If pin 22 is true, indicate to the user that the system is busy,
    // take a photograph and then upload to the cloud.
    if (s_Gpio.InputPin(FileGPIO.FileGPIO.enumPIN.gpio22))
    {
      showReady(false);
      TakeAndSendPicture();
    }
  }
  else
  {
    // Not ready to take a photo yet.
    showReady(false);
    break;
  }
  // Pause for one-tenth of a second.
  System.Threading.Thread.Sleep(100);
}

Há duas formas de verificar o status do pino. A primeira abordagem, aquela que estamos usando aqui, é falar com o sistema de arquivos. Ao verificar por arquivos específicos com os valores específicos, podemos determinar se um pino está ativado ou desativado. Outra abordagem, que geralmente oferece um desempenho mais elevado, é verificar locais específicos na memória em busca de valores específicos. Embora seja mais lento de trabalhar com o sistema de arquivos, é considerado mais seguro. Essa abordagem aproveita o driver integrado que o Linux fornece.

Vamos abordar alguns dos códigos que serão executados além do Mono no Raspberry Pi usando C#. O Raspberry Pi executará quatro etapas básicas. Primeira, ele responderá alguém pressionando o botão da campainha. Segundo, com base no botão da campainha sendo pressionado, ele tirará uma foto e salvará no armazenamento local. Terceira, ele solicitará um token SAS que ele usará para carregar a foto. Quarta, ele carregará a foto no Armazenamento do Azure como um blob. Embora o código seja escrito no C#, é todo baseado no REST. Isso significa que qualquer linguagem ou ambiente com competência de HTTP pode executar essas quatro etapas.

Podemos controlar o Raspberry Pi ao nos comunicarmos com o GPIO. Há somente quatro pontos nos quais nosso aplicativo usará o GPIO 2 para entrada e o GPIO 1 para saída. Apresentaremos alguns códigos C# para a interface com estes pinos. Dê uma olhada no loop principal do código C# do Raspberry Pi C# na Figura 6. Os pinos 17 e 22 são usados para testar a prontidão do dispositivo e para tirar e carregar uma foto com base no pressionamento do botão da campainha.

Esse loop longo de sondagem está constantemente verificando as voltagens dos pinos. Assim o software sabe que algo tem que ser realizado—como tirar uma foto. Este loop é executado em aproximadamente 10hz enquanto ele sonda o status do pin. Se você estiver interessado em saber mais sobre a velocidade de benchmark, acesse bit.ly/1trFzt9.

Várias linguagens operam em diferentes velocidades. Por exemplo, o Python é bastante lento e não é possível usá-lo em cenários onde a velocidade é crucial. Nesse caso, 10hz é rápido o suficiente se o interruptor da campainha puxou o pino 22 para ativar quando alguém pressiona ele.

Cada um dos três pinos realizam uma função diferente. A primeira entrada, o pino 17, deve estar conectado ao pino de terra (que é interpretado pelo C# como false). Se ele não for configurado dessa maneira, o programa encerrará. O pino 22 deve estar definido para Ativado (que é interpretado como true). Quando o pino 22 é true, o processo de tirar foto começa no TakeAndSend­Picture. O método showReady usa o pino 4, um pino de saída, para mostrar que o programa está pronto para tirar foto e carregar imagens ao impulsionar um LED.

A solução aproveita os símbolos de combinação condicional para que o código apropriado seja executado no sistema operacional do Raspbian em contraste com o sistema operacional normal do Windows/Desktop. O código na solução precisa ser diferente, pois tirar uma foto no sistema operacional do Raspbian não é uma chamada de API. Ele envolve a execução de um executável em seu próprio processo. No Windows 8, ao contrário, você aproveita a API CaptureFileAsync da CameraCaptureUI.

Para tirar a foto, chamamos o executável raspistill integrado como mostrado na Figura 7. Ele já está configurado para tirar uma foto e salvá-la como um JPEG. Isso permite que você especifique o nome do arquivo, qualidade da foto e tamanho da imagem. O Raspistill é iniciado como um processo filho. Enquanto a foto está sendo tirada, o código solicita uma URL SAS do Serviço Móvel do Azure. Ele carrega a imagem para o Armazenamento de Blob do Azure.

Figura 7 Tirando uma foto e carregando ela para a nuvem

static void TakeAndSendPicture()
{
#if LINUX
  // Start photo-taking process. This will kick off the raspistill process.
  // We'll wait for it to exit after we get the photo URL.
  Process raspistill = new Process();
  raspistill.StartInfo = new ProcessStartInfo("/usr/bin/raspistill",
    "-n -q " + photoQuality +
    " -o /home/pi/Desktop/me.jpg -h 200 -w 200 -t 500")
    {
      UseShellExecute = false
    };
    raspistill.Start();
#endif
  // Get Photo URL while the picture is being taken.
  WebRequest photoRequest = WebRequest.Create(
    "https://raspberrypiservice.azure-mobile.net/api/getuploadblobsas?");
  photoRequest.Method = "GET";
  photoRequest.Headers.Add("X-ZUMO-APPLICATION", 
    "AIzNtpTdQLjORKJJhTrQWWRSHSnXcN78");
  PhotoResponse photoResp = null;
  using (var sbPhotoResponseStream = 
    photoRequest.GetResponse().GetResponseStream())
  {
    StreamReader sr = new StreamReader(sbPhotoResponseStream);
    string data = sr.ReadToEnd();
    photoResp = JsonConvert.DeserializeObject<PhotoResponse>(data);
  }
  Console.WriteLine("Pushing photo to SAS Url: " + photoResp.sasUrl);
  WebRequest putPhotoRequest = WebRequest.Create(photoResp.sasUrl);
  putPhotoRequest.Method = "PUT";
  putPhotoRequest.Headers.Add("x-ms-blob-type", "BlockBlob");
#if LINUX
  // Wait until the photo is taken.
  raspistill.WaitForExit();
  FileStream fs = new FileStream(@"/home/pi/Desktop/me.jpg", 
    FileMode.Open);
#else
  FileStream fs = new FileStream(@"testPhoto.jpg", FileMode.Open);
#endif
  using (fs)
  using (var reqStream = putPhotoRequest.GetRequestStream())
  {
    Console.WriteLine("Writing photo to blob...");
    fs.CopyTo(reqStream);
  }
  using (putPhotoRequest.GetResponse())
  {
  }
}

A solução do Visual Studio foi desenvolvida para executar em um Raspberry Pi, bem como em um SO do Windows tradicional. A solução aproveita os símbolos de compilação condicionais para que o código apropriado seja executado no sistema operacional do Raspbian em vez de no sistema operacional normal do Windows desktop. O código na solução precisa ser diferente, pois tirar uma foto no sistema operacional do Raspbian é específico da plataforma. Para manter as coisas simples, ao compilar para o Windows 8, não tiramos uma foto. Ao invés, nós carregamos uma imagem existente (testPhoto.jpg) para a nuvem.

A boa notícia é que você pode compartilhar vários códigos entre o Windows e o Raspbian. Tudo é idêntico, de adquirir a SAS até carregar a foto. Então se funciona no Windows, provavelmente funcionará da mesma maneira no Raspbian. Isso simplifica dramaticamente o desenvolvimento e teste do código baseado no cliente. O Raspberry Pi é um dispositivo limitado, portanto, é melhor minimizar o trabalho feito no próprio dispositivo.

Quando o dispositivo tira uma foto, você deve ser capaz de ver ela em dois locais. O primeiro local é no próprio dispositivo, especificamente em /home/pi/Desktop/me.jpg, onde ela foi especificada na linha de comando. Depois, claro, o objetivo é carregar a imagem para o contêiner da Conta de Armazenamento do Azure.

Conclusão

Esse é um ponto inicial sólido para desenvolver seu próprio dispositivo da Internet das Coisas. Tentamos abordar tudo desde obter o hardware, montar, instalar software, escrever software e testar a funcionalidade. Nós também fornecemos várias postagens de blog de suporte. Mas essa solução não está completa.

No próximo artigo, abordaremos a maneira que as notificações por push são enviadas para os telefones para que você possa exibir a foto da pessoa que está tocando sua campainha em um dispositivo móvel. Introduziremos o serviço de notificação, que faz parte do Barramento de Serviço do Azure. Também desenvolveremos um aplicativo do Windows Phone capaz de receber notificações por push do Azure. Finalmente, abordaremos mecanismos de armazenamento adicionais, como usar um banco de dados MongoDB NoSQL e fazer interface com um back-end de reconhecimento de face. Fique atento para mais Internet das Coisas com o Azure.


Bruno Terkaly é desenvolvedor e divulgador da Microsoft. Seu profundo conhecimento é fruto de anos de experiência no campo, escrevendo código para uma grande quantidade de plataformas, linguagens, estruturas, SDKs, bibliotecas e APIs. Ele dedica tempo escrevendo código, publicando no blog e fazendo apresentações ao vivo sobre o desenvolvimento de aplicativos baseados na nuvem, especificamente usando a plataforma do Microsoft Azure. Você pode ler seu blog em blogs.msdn.com/b/brunoterkaly.

Steven Edouard é um desenvolvedor e divulgador da Microsoft. Antes disso, ele trabalhou na equipe do .NET runtime como um engenheiro de teste de software fornecendo produtos como o .NET Framework 4.5 e .NET Native Compilation. Agora sua paixão é fascinar as pessoas sobre os potenciais infinitos dos serviços de computação em nuvem por meio do envolvimento de demonstrações técnicas, conteúdo online a apresentações.

Obrigado pelos seguintes especialistas técnicos da Microsoft por sua revisão: Gil Isaacs e Brent Stineman
Em uma carreira de TI que durou mais de 20 anos, Brent Stineman tem tocado em tudo desde móvel até o mainframe. Atualmente, ele usa sua paixão pela computação em nuvem e a plataforma do Azure para ajudar a capacitar os arquitetos empresários como um evangelista do grupo TED (Technical Evangelism and Development) na divisão DX (Experiência do Desenvolvedor da Microsoft). Você pode seguir o Brent em: twitter.com/brentCodeMonkey.

Gil Isaacs é um evangelista técnico da plataforma do Microsoft Azure na divisão Experiência do Desenvolvedor (DX). Sua função é ajudar os clientes a serem bem sucedidos mais rapidamente na medida em que se envolvem com as arquitetura baseadas na nuvem. A experiência de Gil é baseada em anos dedicados na codificação e em ajudar os clientes a resolver problemas através de uma combinação de tecnologias heterogêneas. Gil atualmente se concentra em trazer as tecnologias de código-fonte aberto para o Azure. Você pode seguir o Gil em twitter.com/gilisaacs.