IoT e MongoDB: impulsionando a análise de séries temporais do consumo doméstico de energia
Avalie esse Tutorial
Os sistemas de IoT (Internet das Coisas) estão se tornando cada vez mais parte de nossa vida diária, oferecendo soluções inteligentes para casas e negócios.
Este artigo explorará um estudos de caso prático sobre o consumo de energia doméstica, mostrando como as coleções de séries temporais do MongoDB podem ser aproveitadas para armazenar, gerenciar e analisar dados gerados por dispositivos IoT de forma eficiente.
As coleções de séries temporais no MongoDB armazenam efetivamente dados de séries temporais — uma sequência de pontos de dados analisados para observar mudanças ao longo do tempo.
As coleções de séries temporais oferecem os seguintes benefícios:
- Menos complexidade para trabalhar com dados de séries temporais
- Mais eficiência da query
- Uso de disco reduzido
- Menos E/S em operações de leitura
- Aumento do uso de cache do WiredTiger
Geralmente, os dados de série temporal são compostos dos seguintes elementos:
- O carimbo de data/hora de cada ponto de dados
- Metadados (também conhecidos como a origem), que são um rótulo ou tag que identifica exclusivamente uma série e raramente mudam
- **Medições** (também conhecidas como métricas ou valores), que representam os pontos de dados rastreados em incrementos de tempo — geralmente pares de valores-chave que mudam ao longo do tempo.
Este estudo de caso se concentra na análise do conjunto de dados com mais de dois milhões de pontos de dados de consumo de energia elétrica doméstica, com uma taxa de amostragem de um minuto ao longo de quase quatro anos.
O conjunto de dados inclui as seguintes informações:
- data: Data no formato dd/mm/aaaa
- tempo: Tempo no formato hh:mm
- global_active_power: Potência ativa média por minuto global do Household (em quilowatts)
- global_reactive_power: Potência reativa média por minuto global doméstica (em quilowatt)
- tensão: Tensão média por minuto (em volts)
- global_intensity: Intensidade de corrente média de minutos global doméstica (em ampères)
- sub_metering_1: sub-medição de energia não. 1 (em segundos-hora de energia ativa); corresponde à cozinha, contendo principalmente uma máquina de servir loj
- sub_metering_2: sub-medição de energia não. 2 (em segundos-hora de energia ativa); corresponde à área de serviço e contém uma máquina de levar, uma máquina de Secar, uma pia e uma pia.
- sub_metering_3: Submedição de energia nº 3 (em watt-hora de energia ativa); corresponde a um aquecedor elétrico de água e a um condicionador de ar
Para definir e modelar nossa coleção de séries temporais, usaremos a bibliotecaMongoose . O Mongoose, uma biblioteca de modelagem de dados de objetos (ODM) para MongoDB, é amplamente usado no ecossistema Node.js por sua capacidade de fornecer uma maneira direta de modelar os dados do aplicativo.
O esquema incluirá:
- timestamp: Uma combinação dos campos "date " e "time " do conjunto de dados.
- potência_ativa_global: Uma representação numérica do conjunto de dados.
- global_reactive_power: Uma representação numérica do conjunto de dados.
- tensão: uma representação numérica do conjunto de dados.
- global_intensity: Uma representação numérica do conjunto de dados.
- sub_metering_1: Uma representação numérica do conjunto de dados.
- sub_metering_2: Uma representação numérica do conjunto de dados.
- sub_metering_3: Uma representação numérica do conjunto de dados.
Para configurar a coleção como uma coleção de séries temporais, é necessária uma configuração adicional “timeseries” com as propriedades “timeField” e “granularity”. O “timeField” usará a propriedade “timestamp” do nosso esquema e “granularity” será definido como “minutes” para corresponder à taxa de amostragem do conjunto dedados.
Além disso, um índice no campo "timestamp " será criado para melhorar o desempenho da query — observe que você pode query uma coleção de séries temporais da mesma forma que faz query de uma collection padrão do MongoDB.
O esquema resultante é estruturado da seguinte forma:
1 const { Schema, model } = require('mongoose'); 2 3 const powerConsumptionSchema = new Schema( 4 { 5 timestamp: { type: Date, index: true }, 6 global_active_power: { type: Number }, 7 global_reactive_power: { type: Number }, 8 voltage: { type: Number }, 9 global_intensity: { type: Number }, 10 sub_metering_1: { type: Number }, 11 sub_metering_2: { type: Number }, 12 sub_metering_3: { type: Number }, 13 }, 14 { 15 timeseries: { 16 timeField: 'timestamp', 17 granularity: 'minutes', 18 }, 19 } 20 ); 21 22 const PowerConsumptions = model('PowerConsumptions', powerConsumptionSchema); 23 24 module.exports = PowerConsumptions;
Para obter mais detalhes sobre a criação de coleções de séries temporais, consulte a documentação oficial de séries temporais do MongoDB.
O conjunto dedados é fornecido como um arquivo .txt, que não pode ser usado diretamente com o MongoDB. Para importar esses dados para nosso MongoDB database, precisamos pré-processá-los para que eles se alinham com o design do esquema do MongoDB database.
Isso pode ser feito executando as seguintes etapas:
- Conecte-se ao MongoDB.
- Carregar dados do .txt Migrator.
- Normalize os dados e divida o conteúdo em linhas.
- Analise as linhas em objetos estruturados.
- Transforma os dados para que correspondam ao nosso modelo de esquema do MongoDB.
- Filtre os dados inválidos.
- Insira os dados finais no MongoDB em pedaços.
Aqui está o script Node.js que automatiza estas etapas:
1 // Load environment variables from .env file 2 require('dotenv').config(); 3 4 // Import required modules 5 const fs = require('fs'); 6 const mongoose = require('mongoose'); 7 const PowerConsumptions = require('./models/power-consumption'); 8 9 // Connect to MongoDB and process the data file 10 const processData = async () => { 11 try { 12 // Connect to MongoDB using the connection string from environment variables 13 await mongoose.connect(process.env.MONGODB_CONNECTION_STRING); 14 15 // Define the file path for the data source 16 const filePath = 'Household_Power_Consumption.txt'; 17 18 // Read data file 19 const rawFileContent = fs.readFileSync(filePath, 'utf8'); 20 21 // Normalize line endings and split the content into lines 22 const lines = rawFileContent.replace(/\r\n/g, '\n').replace(/\r/g, '\n').trim().split('\n'); 23 24 // Extract column headers 25 const headers = lines[0].split(';').map((header) => header.trim()); 26 27 // Parse the lines into structured objects 28 const parsedRecords = lines.slice(1).map((line) => { 29 const values = line.split(';').map((value) => value.trim()); 30 return headers.reduce((object, header, index) => { 31 object[header] = values[index]; 32 return object; 33 }, {}); 34 }); 35 36 // Transform and prepare data for insertion 37 const transformedRecords = parsedRecords.map((item) => { 38 const [day, month, year] = item.Date.split('/').map((num) => parseInt(num, 10)); 39 const [hour, minute, second] = item.Time.split(':').map((num) => parseInt(num, 10)); 40 const dateObject = new Date(year, month - 1, day, hour, minute, second); 41 42 return { 43 timestamp: dateObject.toISOString(), 44 global_active_power: parseFloat(item.Global_active_power), 45 global_reactive_power: parseFloat(item.Global_reactive_power), 46 voltage: parseFloat(item.Voltage), 47 global_intensity: parseFloat(item.Global_intensity), 48 sub_metering_1: parseFloat(item.Sub_metering_1), 49 sub_metering_2: parseFloat(item.Sub_metering_2), 50 sub_metering_3: parseFloat(item.Sub_metering_3), 51 }; 52 }); 53 54 // Filter out invalid data 55 const finalData = transformedRecords.filter( 56 (item) => 57 item.timestamp !== 'Invalid Date' && 58 !isNaN(item.global_active_power) && 59 !isNaN(item.global_reactive_power) && 60 !isNaN(item.voltage) && 61 !isNaN(item.global_intensity) && 62 !isNaN(item.sub_metering_1) && 63 !isNaN(item.sub_metering_2) && 64 !isNaN(item.sub_metering_3) 65 ); 66 67 // Insert final data into the database in chunks of 1000 68 const chunkSize = 1000; 69 for (let i = 0; i < finalData.length; i += chunkSize) { 70 const chunk = finalData.slice(i, i + chunkSize); 71 await PowerConsumptions.insertMany(chunk); 72 } 73 74 console.log('Data processing and insertion completed.'); 75 } catch (error) { 76 console.error('An error occurred:', error); 77 } 78 }; 79 80 // Call the processData function 81 processData();
Antes de iniciar o script, você precisa se certificar de que suas variáveis de ambiente estejam configuradas corretamente. Para fazer isso, crie um arquivo chamado ".env " na pasta raiz e adicione uma linha para "MONGODB_CONNECTION_STRING ", que é o seu link para o MongoDB database.
O conteúdo do arquivo .env deve ficar assim:
1 MONGODB_CONNECTION_STRING = 'mongodb+srv://{{username}}:{{password}}@{{your_cluster_url}}/{{your_database}}?retryWrites=true&w=majority'
Para obter mais detalhes sobre a construção de sua connection string, consulte a documentação oficial do MongoDB.
Depois que os dados forem inseridos em nossa coleção de séries temporais do MongoDB, oMongoDB Atlas Charts pode ser usado para se conectar e visualizar os dados sem esforço.
Para conectar e usar o MongoDB Atlas Charts, devemos:
- Estabeleça uma conexão com a coleta de séries temporais como fonte de dados.
- Associe os campos desejados aos eixos X e Y apropriados.
- Implemente filtros conforme necessário para refinar os dados exibidos.
- Explore as visualizações fornecidas pelos Atlas Charts para obter insights.
No exemplo acima, visualizamos o consumo de energia de várias fontes em um único dia. A visualização revelou padrões de uso distintos: O equipamento da cozinha era usado principalmente de manhã e à noite, o equipamento da lavanderia estava ativo por volta do meio-dia, e o aquecedor de água e o ar-condicionado apresentavam uso contínuo de manhã à noite.
Para a visualização exibida, usamos uma consulta para filtrar os dados para uma data específica:
1 { timestamp: { $gt: ISODate('2007-01-17T00:00:00.000-00:00'), $lt: ISODate('2007-01-18T00:00:00.000-00:00') } }
Se você quiser alterar o que é mostrado nos gráficos, poderá aplicar diferentes filtros ou pipelines de agregação aos dados, adaptando os resultados de acordo com suas necessidades.
Este artigo demonstra os poderosos recursos do MongoDB quando integrado com sistemas IoT. Ao aproveitar a coleção de séries temporais do MongoDB, podemos armazenar, gerenciar e analisar com eficiência os grandes volumes de dados de séries temporais gerados por dispositivos IoT.
O pesquisa de caso sobre o consumo de energia doméstica não apenas mostra as aplicações práticas da IoT em nossa vida diária, mas também destaca como o MongoDB pode nos ajudar a obter uma compreensão mais profunda dos conjuntos de dados de IoT.
Por meio da visualização com o MongoDB Atlas Charts, obtivemos insights significativos sobre padrões de consumo de energia. Isso não só ajuda na tomada de decisões informadas, mas também abre as portas para melhorias significativas na eficiência energética e na economia de custos.
Como examinamos os recursos do MongoDB em lidar com dados de IoT e visualizá-los com o Atlas Charts, espero que você se emocione para trabalhar mais em seus próprios projetos de dados. Convido você a participar dos Fóruns da MongoDB Community para compartilhar suas experiências, fazer perguntas e colaborar com outrosentusiastas. Esteja você procurando conselhos, compartilhando seu projeto mais recente ou explorando usos inovadores do MongoDB, a comunidade é um ótimo lugar para continuar a conversa.
Principais comentários nos fóruns
Ainda não há comentários sobre este artigo.