Como enviar dados do sensor de ambiente em tempo real do Azure RTOS para o Hub IoT
O sensor atualizado de temperatura, pressão e umidade do laboratório de microbiologia está funcionando bem no núcleo de tempo real do Azure Sphere. O cliente está feliz e pode executar seus experimentos. O cliente também gostaria de monitorar remotamente as condições do laboratório.
Nesta unidade, você aprenderá a ler dados do sensor de laboratório atualizado e a enviar os dados ao Hub IoT para monitoramento.
Arquitetura da solução
Veja a seguir uma descrição de como um aplicativo de alto nível do Azure Sphere pode ler dados do sensor de laboratório atualizado em execução em um dos núcleos de tempo real do Azure Sphere. O aplicativo de alto nível enviará esses dados com segurança para o Hub IoT.
Para recapitular a arquitetura da solução introduzida no laboratório do Azure RTOS.
- O thread do sensor de ambiente de tempo real do Azure RTOS é executado a cada 2 segundos. O thread armazena na memória os dados mais recentes de temperatura, umidade e pressão do ambiente.
- O aplicativo de streaming de telemetria de alto nível solicita do núcleo de tempo real os dados mais recentes do ambiente.
- O thread do serviço de ambiente de tempo real do Azure RTOS responde com os dados mais recentes do ambiente.
- O aplicativo de alto nível serializa os dados do ambiente como JSON e envia a mensagem de telemetria para o Hub IoT.
- O Azure IoT Explorer assina as mensagens de telemetria enviadas ao Hub IoT pelo dispositivo e exibe a telemetria.
- Você também pode definir a temperatura desejada para o local definindo uma propriedade. A propriedade é definida no dispositivo por meio de uma mensagem de dispositivo gêmeo do Hub IoT.
- Em seguida, o Azure Sphere define o modo de operação do HVAC para chegar à temperatura desejada.
Contrato de mensagem entre núcleos
Precisa haver um contrato que descreva a forma dos dados que estão sendo passados entre os núcleos. A estrutura a seguir declara o contrato entre núcleos usado nesta unidade. Encontre esse contato no diretório IntercoreContract.
typedef enum
{
LP_IC_UNKNOWN,
LP_IC_HEARTBEAT,
LP_IC_ENVIRONMENT_SENSOR,
LP_IC_SAMPLE_RATE
} LP_INTER_CORE_CMD;
typedef struct
{
LP_INTER_CORE_CMD cmd;
float temperature;
float pressure;
float humidity;
int sample_rate;
} LP_INTER_CORE_BLOCK;
Segurança entre núcleos
Para se comunicar, os aplicativos em execução nos núcleos precisam ser configurados com as IDs de Componente correspondentes.
A ID do componente do aplicativo em tempo real pode ser encontrada no arquivo app_manifest.json dele.
{
"SchemaVersion": 1,
"Name": "AzureSphereIoTCentral",
"ComponentId": "25025d2c-66da-4448-bae1-ac26fcdd3627",
...
}
Funcionalidades entre núcleos de alto nível
A propriedade AllowedApplicationConnections no arquivo app_manifest.json de alto nível é definida como a ID do componente do aplicativo de tempo real do Azure RTOS.
{
...
"AllowedApplicationConnections": [ "6583cf17-d321-4d72-8283-0b7c5b56442b" ]
...
}
Inicializando comunicações entre núcleos
No InitPeripheralAndHandlers, é feita uma chamada para lp_interCoreCommunicationsEnable, passando a ID do componente de tempo real e da função de retorno de chamada entre núcleos.
A função de retorno de chamada entre núcleos será chamada quando for recebida uma mensagem do núcleo de tempo real.
lp_interCoreCommunicationsEnable(REAL_TIME_COMPONENT_ID, InterCoreHandler); // Initialize Inter Core Communications
Enviar uma solicitação ao aplicativo do núcleo de tempo real
Para solicitar dados de ambiente do núcleo de tempo real:
- Defina o comando de bloco de controle entre núcleos como LP_IC_ENVIRONMENT_SENSOR.
- Envie a mensagem de solicitação chamando lp_interCoreSendMessage e passando o bloco de controle entre núcleos.
/// <summary>
/// Read sensor and send to Azure IoT
/// </summary>
static void MeasureSensorHandler(EventLoopTimer* eventLoopTimer)
{
if (ConsumeEventLoopTimerEvent(eventLoopTimer) != 0)
{
lp_terminate(ExitCode_ConsumeEventLoopTimeEvent);
}
else {
// send request to Real-Time core app to read temperature, pressure, and humidity
ic_control_block.cmd = LP_IC_ENVIRONMENT_SENSOR;
lp_interCoreSendMessage(&ic_control_block, sizeof(ic_control_block));
}
}
Recebendo mensagens entre núcleos
Quando o aplicativo de alto nível recebe uma mensagem, a função de retorno de chamada entre núcleos é chamada, passando uma referência para o bloco de controle entre núcleos que contém os dados do ambiente. O aplicativo serializa os dados como JSON, envia a mensagem de telemetria ao Hub IoT e o LED de status do HVAC é atualizado.
/// <summary>
/// Callback handler for Inter-Core Messaging - Does Device Twin Update, and Event Message
/// </summary>
static void InterCoreHandler(LP_INTER_CORE_BLOCK* ic_message_block)
{
static int msgId = 0;
switch (ic_message_block->cmd)
{
case LP_IC_ENVIRONMENT_SENSOR:
if (snprintf(msgBuffer, JSON_MESSAGE_BYTES, msgTemplate, ic_message_block->temperature,
ic_message_block->humidity, ic_message_block->pressure, msgId++) > 0) {
Log_Debug("%s\n", msgBuffer);
lp_azureMsgSendWithProperties(msgBuffer, telemetryMessageProperties, NELEMS(telemetryMessageProperties));
SetHvacStatusColour((int)ic_message_block->temperature);
// If the previous temperature not equal to the new temperature then update ReportedTemperature device twin
if (previous_temperature != (int)ic_message_block->temperature) {
lp_deviceTwinReportState(&dt_reportedTemperature, &ic_message_block->temperature);
previous_temperature = (int)ic_message_block->temperature;
}
}
break;
default:
break;
}
}