<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>InfluxData Blog - Zoe Steinkamp</title>
    <description>Posts by Zoe Steinkamp on the InfluxData Blog</description>
    <link>https://www.influxdata.com/blog/author/zoe-steinkamp/</link>
    <language>en-us</language>
    <lastBuildDate>Tue, 04 Jun 2024 08:00:00 +0000</lastBuildDate>
    <pubDate>Tue, 04 Jun 2024 08:00:00 +0000</pubDate>
    <ttl>1800</ttl>
    <item>
      <title>Chasing the Skies: Monitoring Flights with InfluxDB</title>
      <description>&lt;p&gt;We’re in an era where every move is monitored, where fans track every step of Taylor Swift’s jet-setting lifestyle. While some may dream of spotting celebrities at 30,000 feet, aviation enthusiasts and tech professionals see a broader horizon for flight traffic and monitoring.&lt;/p&gt;

&lt;p&gt;Enter InfluxDB, the robust time series database transforming how we monitor flights in real-time. Whether it’s keeping tabs on a pop star’s private plane or ensuring commercial flights run on schedule, InfluxDB offers unprecedented insights into aviation data.&lt;/p&gt;

&lt;p&gt;In this blog post, we’ll learn how to leverage &lt;a href="https://www.flightaware.com/"&gt;FlightAware&lt;/a&gt; and &lt;a href="https://www.influxdata.com/products/influxdb-overview/?utm_source=google&amp;amp;utm_medium=cpc&amp;amp;utm_campaign=UP%20-%20NA%20Search%20%7C%20Brand-Related%20-%20InfluxDB%20Cloud%20Free%20Tier%20tCPA%20vs%20CPC%20Bidding%20Brand%20Campaign&amp;amp;utm_term=influx%20db&amp;amp;gclid=CjwKCAjw-7OlBhB8EiwAnoOEkwBTlNjA8OGe19RBzbO2tJGL3fMO48eVyW0l6Eeg6YHVkq7xWsIfARoCMAwQAvD_BwE"&gt;InfluxDB Cloud 3&lt;/a&gt; to monitor private/GA flight and airport delays. Then, we’ll use &lt;a href="https://www.influxdata.com/grafana/"&gt;Grafana&lt;/a&gt; to build a flight monitoring dashboard. Find the corresponding &lt;a href="https://github.com/InfluxCommunity/Flight-Demo/tree/main"&gt;repo here&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id="requirements"&gt;Requirements&lt;/h2&gt;

&lt;p&gt;To run this example, you’ll need the following:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Python 3&lt;/li&gt;
  &lt;li&gt;Pandas&lt;/li&gt;
  &lt;li&gt;Requests&lt;/li&gt;
  &lt;li&gt;&lt;a href="https://github.com/InfluxCommunity/influxdb3-python"&gt;influxdb_client_3&lt;/a&gt;&lt;u&gt;&lt;/u&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href="https://www.flightaware.com/commercial/aeroapi/"&gt;Flight Aware API&lt;/a&gt;&lt;u&gt;&lt;/u&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href="https://www.influxdata.com/"&gt;InfluxDB 3 Cloud Account&lt;/a&gt;&lt;u&gt;&lt;/u&gt;&lt;/li&gt;
  &lt;li&gt;Optional: &lt;a href="https://grafana.com/"&gt;Grafana Dashboard&lt;/a&gt;&lt;u&gt;&lt;/u&gt;&lt;/li&gt;
  &lt;li&gt;Optional: &lt;a href="https://openskynetwork.github.io/opensky-api/"&gt;Open Sky API&lt;/a&gt;&lt;u&gt;&lt;/u&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You’ll also need to gather authentication credentials from your InfluxDB and FlightAware accounts. Follow these docs to learn more about how to get these credentials:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Bucket&lt;/li&gt;
  &lt;li&gt;Token&lt;/li&gt;
  &lt;li&gt;InfluxDB URL&lt;/li&gt;
  &lt;li&gt;&lt;a href="https://www.flightaware.com/commercial/aeroapi/#compare-plans-section"&gt;FlightAware API Key&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Please note that InfluxDB Cloud 3 offers a free tier, but you’ll need to pay for a Standard FlightAware tier to access that API. However, you can also leverage &lt;a href="https://github.com/InfluxCommunity/Flight-Demo/tree/main/test%20files"&gt;test JSON files and a test python script&lt;/a&gt; in the repo  to try this example out before paying for live data from FlightAware.&lt;/p&gt;

&lt;h2 id="using-the-influxdb-v3-python-client-library-to-get-flight-data"&gt;Using the InfluxDB v3 Python Client Library to get flight data&lt;/h2&gt;

&lt;p&gt;At the core of this example is a Python Script, &lt;a href="http://flightAware.py"&gt;flightAware.py&lt;/a&gt;. This Python script continuously monitors and collects data about flights within specific geographic boundaries using the FlightAware AeroAPI and InfluxDB, a time-series database. The script fetches live flight data every 5 minutes. Here’s a breakdown of its key components:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Environment and Libraries: First, we import all libraries and modules, such as os, requests, pandas, and influxdb_client_3. We also import datetime, timezone, and custom secret modules for secure the handling of sensitive information like API keys.&lt;/li&gt;
  &lt;li&gt;Configure Variables: Next, we set up variables for database (db), organization (org), and API (url) configuration. We also retrieve authentication tokens (token) and API keys (apikey) using environment variables and a custom secret.py file. This example assumes you created a secret.py and stored your credentials there.&lt;/li&gt;
  &lt;li&gt;Configure the InfluxDB v3 Python Client: We initialize an InfluxDBClient3 object with the specified host URL, token, and organization details for data storage.&lt;/li&gt;
&lt;/ol&gt;

&lt;pre&gt;&lt;code class="language-python"&gt;python
influxdbClient = InfluxDBClient3(host=url, token=token, org=org)
&lt;/code&gt;&lt;/pre&gt;

&lt;ol&gt;
  &lt;li&gt;API Configuration and Headers: Using the API key, define the FlightAware AeroAPI endpoint and authentication header. Specify the parameters for the API request, including a geographic bounding box for flight tracking and a limit on the number of pages returned.&lt;/li&gt;
  &lt;li&gt;Time Conversion Function: Include a function convert_to_utc to ensure all timestamps are in UTC. This facilitates easier data management and visualization in Grafana.&lt;/li&gt;
  &lt;li&gt;Main Loop for Data Collection: This executes a perpetual loop that sends requests to the FlightAware AeroAPI to retrieve flight data within the specified parameters. It also checks if the response is successful and extracts flight details, specifically ignoring flights without a declared destination. For each valid flight, it constructs a detailed dictionary including flight identifiers, timing, geographical coordinates, and other pertinent flight data. The script also handles waypoints, extracting only the first and last for simplicity.&lt;/li&gt;
  &lt;li&gt;Data Handling and Storage: Here, we merge all collected flight data into a single dictionary and convert it into a Pandas DataFrame. Then, we write this DataFrame to InfluxDB, specifying measurement and tagging configurations.&lt;/li&gt;
&lt;/ol&gt;

&lt;pre&gt;&lt;code class="language-python"&gt;python
 for d in flight_data:
                        merged_data.update(d)
                    flight_df = pd.DataFrame([merged_data])
                    flight_df['timestamp'] = flight_df['last_position']
                    influxdbClient._write_api.write(bucket=db, record=flight_df, data_frame_measurement_name='flight', data_frame_tag_columns=['ident', 'fa_flight_id'], data_frame_timestamp_column='timestamp')
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Visualizing flight data in Grafana&lt;/p&gt;

&lt;p&gt;Now you can import the &lt;a href="https://github.com/InfluxCommunity/Flight-Demo/blob/main/FlightAware-1716010667022.json"&gt;FlightAware Grafana Dashboard JSON&lt;/a&gt; to build a Flight Monitoring Dashboard in Grafana. For more information on importing a dashboard from JSON in Grafana please see &lt;a href="https://grafana.com/docs/grafana/latest/dashboards/build-dashboards/import-dashboards/"&gt;this documentation&lt;/a&gt;. To query data from an InfluxDB Cloud 3 free-tier account, leverage the &lt;a href="https://www.influxdata.com/blog/official-influxdb-v3-data-source-grafana-released/"&gt;Grafana InfluxDB v3 Data Source&lt;/a&gt;.
&lt;img src="//images.ctfassets.net/o7xu9whrs0u9/187c294f64c04194a81e1d96ebab6f2a/84c50db97b2c8a3e5fae871b1d504adf/Screenshot_2024-05-14_at_10.49.06_PM.png" alt="" /&gt;
&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;Here we can see the planes in our specific area, as visualized by the map on the top left panel in this dashboard. For this example, we focus on Las Vegas. We can also look at aircraft types, destination cities, and origin cities (top right panels). We also monitor stats like average altitude, number of flights in the air, and average ground speed. We also have an Airplane Ground speed time series visualization to see how planes land and take off.&lt;/p&gt;

&lt;p&gt;I don’t know much about different aircraft, but I imagine larger airplanes have a steeper landing and take-off speed. Finally, we also visualize the flights by major airlines, with Southwest Airlines having the most flights in Las Vegas at that time.&lt;/p&gt;

&lt;h2 id="additional-resources-and-conclusion"&gt;Additional resources and conclusion&lt;/h2&gt;

&lt;p&gt;We hope this tutorial helps you get started visualizing flight data with InfluxDB. We also want to encourage you to take a look a the following related resources to learn more about how to leverage InfluxDB with Grafana and Python:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href="https://www.influxdata.com/blog/client-library-deep-dive-python-part-1/"&gt;Client Library Deep Dive: Python (Part 1)&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href="https://www.influxdata.com/blog/client-library-deep-dive-python-part-2/"&gt;Client Library Deep Dive: Python (Part 2)&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href="https://www.influxdata.com/blog/influxdb-3-python-client-update-polars/"&gt;InfluxDB 3 Python Client Update: Adding Polars Support&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;Grafana Unleashes Official InfluxDB V3 Data Source: A Quick-start Guide to Configuration and Usage&lt;/li&gt;
  &lt;li&gt;&lt;a href="https://www.influxdata.com/blog/alerting-with-grafana-and-influxdb-cloud-serverless/"&gt;Alerting with Grafana and InfluxDB Cloud Serverless&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;Note: Another cool thing about this demo is that the DevRel team at InfluxData can run it entirely with Github Actions, so if you see InfluxData at a conference booth running this demo, it’s likely we’re running it remotely.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;As always, get started with &lt;a href="https://www.influxdata.com/products/influxdb-overview/?utm_source=google&amp;amp;utm_medium=cpc&amp;amp;utm_campaign=UP%20-%20NA%20Search%20%7C%20Brand-Related%20-%20InfluxDB%20Cloud%20Free%20Tier%20tCPA%20vs%20CPC%20Bidding%20Brand%20Campaign&amp;amp;utm_term=influx%20db&amp;amp;gclid=CjwKCAjw-7OlBhB8EiwAnoOEkwBTlNjA8OGe19RBzbO2tJGL3fMO48eVyW0l6Eeg6YHVkq7xWsIfARoCMAwQAvD_BwE"&gt;InfluxDB Cloud 3 here&lt;/a&gt;. If you need help, please contact our &lt;a href="https://community.influxdata.com/"&gt;community site&lt;/a&gt; or &lt;a href="https://influxdata.com/slack"&gt;Slack channel&lt;/a&gt;.&lt;/p&gt;
</description>
      <pubDate>Tue, 04 Jun 2024 08:00:00 +0000</pubDate>
      <link>https://www.influxdata.com/blog/monitoring-flights-influxdb/</link>
      <guid isPermaLink="true">https://www.influxdata.com/blog/monitoring-flights-influxdb/</guid>
      <category>Developer</category>
      <author>Anais Dotis-Georgiou, Zoe Steinkamp (InfluxData)</author>
    </item>
    <item>
      <title>Best Practices for Collecting and Querying Data from Multiple Sources </title>
      <description>&lt;p&gt;&lt;em&gt;This article was originally published in &lt;a href="https://thenewstack.io/best-practices-collect-and-query-data-from-multiple-sources/"&gt;The New Stack&lt;/a&gt; and is reposted here with permission.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;In today’s data-driven world, the ability to collect and query data from multiple sources has become a very important consideration. With the rise of IoT, cloud computing and distributed systems, organizations face the challenge of handling diverse data streams effectively. It’s common to have multiple databases/data storage options for that data. For many large companies, the days of storing everything in the singular database are in the past.&lt;/p&gt;

&lt;p&gt;It is crucial to implement best practices for efficient data collection and querying to maximize your datastores’ potential. This includes optimizing data ingestion pipelines, designing appropriate schema structures and utilizing advanced querying techniques. On top of this, you need data stores that are flexible when querying data back out and are compatible with other data stores.&lt;/p&gt;

&lt;p&gt;By adhering to these best practices, organizations can unlock the true value of their data and gain actionable insights to drive business growth and innovation. This is where &lt;a href="https://www.influxdata.com/"&gt;InfluxDB&lt;/a&gt;, a powerful time series database, comes into play. InfluxDB provides a robust solution for managing and &lt;a href="https://www.influxdata.com/time-series-analysis-methods/"&gt;analyzing time-stamped&lt;/a&gt; data, allowing organizations to make informed decisions based on real-time insights.&lt;/p&gt;

&lt;h2 id="understanding-different-data-sources"&gt;Understanding different data sources&lt;/h2&gt;

&lt;p&gt;When it comes to data collection, it is crucial to explore different data sources and understand their unique characteristics. This involves identifying the types of data available, their formats and the potential challenges associated with each source. After identifying the data sources, selecting the appropriate data ingestion methods becomes essential. This involves leveraging APIs, utilizing &lt;a href="https://www.influxdata.com/products/integrations/"&gt;Telegraf plugins&lt;/a&gt; or implementing batch writes, depending on the specific requirements and constraints of the data sources.&lt;/p&gt;

&lt;p&gt;It’s very important to keep in mind data space and speed. For example, we find with IoT data these are top concerns. Ensuring data integrity and consistency throughout the collection process is of utmost importance. So, too, is having backup plans for data loss, stream corruption and storage at the edge. This involves implementing robust mechanisms to handle errors, to handle duplicate or missing data and to validate the accuracy of the collected data. Additionally, implementing proper data tagging and organization strategies results in efficient data management and retrieval. By tagging data with relevant metadata and organizing it in a structured manner, it becomes easier to search, filter and analyze effectively.&lt;/p&gt;

&lt;p&gt;It’s helpful to note here that most data storage solutions come with their own recommendations for how to begin collecting data into the system. For InfluxDB, we always suggest Telegraf, our open source data ingestion agent. Or for language specific needs we suggest our &lt;a href="https://docs.influxdata.com/influxdb/cloud-serverless/reference/client-libraries/v3/"&gt;client libraries&lt;/a&gt; written in Go, Java, Python, C# and JavaScript. The important takeaway here is to go with recommended and well-documented tools. While it might be tempting to use a tool you are already familiar with, if it’s not recommended you might be missing out on those mechanisms for handling problems.&lt;/p&gt;

&lt;p&gt;&lt;img src="//images.ctfassets.net/o7xu9whrs0u9/2L0JlhGozMNMyD9cuJJEOZ/c793d66c7e35d21481d75bff414a7f39/telegraf-open-source-data-ingestion-agent.png" alt="telegraf-open-source-data-ingestion-agent" /&gt;&lt;/p&gt;

&lt;h2 id="effective-data-modeling"&gt;Effective data modeling&lt;/h2&gt;

&lt;p&gt;Effective &lt;a href="https://www.influxdata.com/blog/data-modeling-part-1-goals-methodology/"&gt;data modeling&lt;/a&gt; is a crucial aspect of building robust and scalable data systems. It involves understanding the structure and relationships of data entities and designing schemas that facilitate efficient data storage, retrieval and analysis. A well-designed data model provides clarity, consistency and integrity to the data, ensuring its accuracy and reliability. The most important piece when dealing with multiple data sources is determining your “connector”, or your data piece that connects your data together.&lt;/p&gt;

&lt;p&gt;For example, let’s look at a generator that has two separate datasets: one in a &lt;a href="https://www.influxdata.com/glossary/sql/"&gt;SQL&lt;/a&gt; database storing the units stats and one in the InfluxDB database that has real-time data about the battery capacity. You might need to identify a faulty generator and its owner based on these two data sets. It might seem like common sense that you would have some kind of shared ID between these two data sets. But when you are first modeling your data, the concern is less about being able to combine data sets and more about the main data use case and removing unnecessary data. Also the other question is: how unique is your connector and how easy will it be to store? For this example, the real-time battery storage might not have easy access to a serial number. That might need to be a hardcoded value added to all data collected from the generator.&lt;/p&gt;

&lt;p&gt;&lt;img src="//images.ctfassets.net/o7xu9whrs0u9/2ZhLHdUmmFrl5xr8tejii8/3cfb4f1147f472475fc9f596b5d6ad35/generator-data.png" alt="generator-data" /&gt;&lt;/p&gt;

&lt;p&gt;Furthermore, as data evolves over time and variations occur, it becomes essential to employ strategies to handle these changes effectively. This may involve techniques such as versioning, migration scripts or implementing dynamic schema designs to accommodate new data attributes or modify existing ones.&lt;/p&gt;

&lt;p&gt;For example, if our generator adds new data sets, it’s important that we add our original connector to that new data. But what if you are dealing with an existing data set? Then it gets trickier. You might have to go back and retroactively implement your connector. In this example, maybe the app where people register their generator and view their battery information, you require them to manually enter their serial number. This allows you to tag them as the owner, and you can run analysis on their device from a distance to determine if it’s within normal range.&lt;/p&gt;

&lt;p&gt;Obviously this is a very simple example, but many companies and industries use this concept. The idea of data living in a vacuum is starting to disappear as many stakeholders expect to access multiple data sources and have an easy way to combine the data sets. So let’s start to dive into how to combine data sets once you have them. Let’s continue from our previous example with InfluxDB and a SQL database, a common use case for combining data.&lt;/p&gt;

&lt;p&gt;When it comes to querying your data, and especially when it comes to combining data sets, there are a couple of recommended tools to accomplish this task. First is SQL, which is broadly used to query many data sources, including InfluxDB. And when it comes to data manipulation and analysis, a second tool, Pandas, is useful for flexible and efficient data processing. &lt;a href="https://pandas.pydata.org/getting_started.html"&gt;Pandas&lt;/a&gt; is a python library that is agnostic to the data it accepts, as long as it’s within a pandas data frame. Many data sources document how to convert their data streams into a pandas dataframe because it is such a popular tool.&lt;/p&gt;

&lt;p&gt;The following code is an example of a SQL query in InfluxDB, which returns the average battery level over the past week for this specific device (via serial number):&lt;/p&gt;

&lt;p&gt;&lt;img src="//images.ctfassets.net/o7xu9whrs0u9/3aZ4kklAIfubylgs7WUA58/957bcdff55fe726387f0ff40e44b0446/sql-query-influxdb.png" alt="sql-query-influxdb" /&gt;&lt;/p&gt;

&lt;p&gt;This query would happen on the app side. When a user logs in and registers their generator’s serial number, that enables you to store the data with a serial number tag to use for filtering. For the readability of this query, it’s easier to imagine all generator data goes into one large database. In reality, it’s more possible that each serial number would be a unique data storage, especially if you wanted to offer customers the chance to “Store your data longer for a fee”, which is a common offer for some businesses and use cases, like residential solar panels.&lt;/p&gt;

&lt;p&gt;Now, this is just one query, but an app developer would likely write several such queries to cover averages for the day and week, and to account for battery usage, battery levels and most recent values, etc. Ultimately, they hope to end up with between 10 and 20 values that they can show to the end user. You can find a list of all these functions for InfluxDB &lt;a href="https://docs.influxdata.com/influxdb/cloud-serverless/reference/sql/functions/"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Once they have these values they can combine all those data points with their SQL database that houses customer data, things like name, address, etc. They can use the InfluxDB &lt;a href="https://github.com/InfluxCommunity/influxdb3-python"&gt;Python client library&lt;/a&gt; to combine their two datasets in Pandas.&lt;/p&gt;

&lt;p&gt;&lt;img src="//images.ctfassets.net/o7xu9whrs0u9/2lP0XPk83kotVHFXTRLHO/fb04b8a7df69da581719f2c517dd1beb/combine-two-datasets-pandas.png" alt="combine-two-datasets-pandas" /&gt;&lt;/p&gt;

&lt;p&gt;This is an example of what that join would look like in the end. When it comes to joining, Pandas has a few options. In this example, I’m using an inner join because I don’t want to lose any of the data from my two data sets. You would probably need to rename some columns, but overall this query results in a combined data frame that you can then convert as needed for use.&lt;/p&gt;

&lt;p&gt;You can imagine how data scientists might use these tools to run anomaly detection on the datasets to identify faulty devices and alert customers to the degradation and needed repairs. If there is a charge for storing data, users can also combine this data with a financial data set to confirm which customers pay for extended storage time and possibly receive extra information. Even in this simple example, there are many stakeholders, and at scale the number of people who need to access and use multiple data sets only expands.&lt;/p&gt;

&lt;h2 id="key-takeaways"&gt;Key takeaways&lt;/h2&gt;

&lt;p&gt;With so much data in the world, the notion of storing everything in a single database or data store may seem tempting. (To be clear, you may want to store all of the same type of data in a single database, e.g., time series data.) While it can be a viable solution at a small scale, the reality is that both small- and large-scale companies can benefit from the cost savings, efficiency improvements and enhanced user experiences that arise from utilizing multiple data sources. As the industries evolve, engineers must adapt and become proficient in working with multiple data stores, and the ability to seamlessly collect and query data from diverse sources becomes increasingly important. Embracing this approach enables organizations to leverage the full potential of their data and empowers engineers to navigate the ever-expanding landscape of data management with ease.&lt;/p&gt;
</description>
      <pubDate>Mon, 14 Aug 2023 07:35:00 +0000</pubDate>
      <link>https://www.influxdata.com/blog/best-practices-for-collecting-and-querying-data-from-multiple-sources/</link>
      <guid isPermaLink="true">https://www.influxdata.com/blog/best-practices-for-collecting-and-querying-data-from-multiple-sources/</guid>
      <category>Developer</category>
      <author>Zoe Steinkamp (InfluxData)</author>
    </item>
    <item>
      <title>Build A Plant Monitoring Tool With IoT: A Beginner-Friendly Tutorial</title>
      <description>&lt;p&gt;&lt;em&gt;This article was originally published in &lt;a href="https://thenewstack.io/building-a-plant-monitoring-tool-with-iot/"&gt;The New Stack&lt;/a&gt; and is reposted here with permission.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Creating an Internet of Things (IoT) app to monitor a house plant is a pragmatic starting place to learn about data that changes over time. It’s useful for anyone who loves the idea of indoor gardening but forgets to check their plants regularly.&lt;/p&gt;

&lt;p&gt;This project is accessible to everyone from students working on a science fair project to botanists monitoring exotic plant nurseries. There are many ways to monitor a house plant, but this is the high-tech way — with sensors and advanced software systems.&lt;/p&gt;

&lt;p&gt;For this project, we’ll use InfluxDB, a time series platform that specializes in storing sequential data as it appears over time. This is useful when comparing data, creating alerts for specific thresholds and monitoring events in the physical and virtual worlds alike.&lt;/p&gt;

&lt;p&gt;&lt;img src="//images.ctfassets.net/o7xu9whrs0u9/2HEtdsnNpECZh8L3H9ltDo/d62c3a1b7878baa2b89b88a4b2b485ea/mmonitoring_a_plant.png" alt="mmonitoring a plant" /&gt;&lt;/p&gt;

&lt;p&gt;The full list of supplies, a schematic drawing for your breadboard (with microcontroller of choice) and the source code are all available from my &lt;a href="https://github.com/InfluxCommunity/plant_buddy_iox"&gt;git repository&lt;/a&gt; if you want to follow along for your own edification or desperately need to keep a houseplant alive.&lt;/p&gt;

&lt;h2 id="the-architecture"&gt;The architecture&lt;/h2&gt;

&lt;p&gt;&lt;img src="//images.ctfassets.net/o7xu9whrs0u9/1UldSPiTrghLY2nRdLz1Fc/7807a0c0bcf28cbec9a9d026532ba6bf/the_architecture.png" alt="the architecture" /&gt;&lt;/p&gt;

&lt;p&gt;An IoT sensor tracks my plant’s health metrics at timed intervals. We classify the data it collects as time series data because it includes a timestamp, which appears as the first column in storage. The IoT sensors generate data about the plant’s health. Then I use &lt;a href="https://www.influxdata.com/time-series-platform/telegraf/"&gt;Telegraf&lt;/a&gt;, an open source collection agent, and the Python &lt;a href="https://www.influxdata.com/products/data-collection/influxdb-client-libraries/"&gt;client library&lt;/a&gt; to collect that data and send it to the storage layer, InfluxDB. The &lt;a href="https://plotly.com/python/"&gt;Plotly&lt;/a&gt; graphing library provides the data visualization. I coded the project in Python and it uses the Flask library for routing.&lt;/p&gt;

&lt;h2 id="getting-started"&gt;Getting started&lt;/h2&gt;

&lt;p&gt;Instruments:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;A plant to monitor&lt;/li&gt;
  &lt;li&gt;A Particle Boron or &lt;a href="https://opensource.com/article/19/12/seeeduino-nano-review"&gt;similar microcontroller&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;At least one IoT sensor for your plant&lt;/li&gt;
  &lt;li&gt;A breadboard&lt;/li&gt;
  &lt;li&gt;Jump wires&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I use four sensors to generate the following five data points:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Air temperature&lt;/li&gt;
  &lt;li&gt;Humidity&lt;/li&gt;
  &lt;li&gt;Light&lt;/li&gt;
  &lt;li&gt;Soil temperature&lt;/li&gt;
  &lt;li&gt;Soil moisture&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;img src="//images.ctfassets.net/o7xu9whrs0u9/2ue12EhRKqE9x8eUOuAgbA/213aa626642a3e8dc526092ac8c1cf40/schematics_and_sensors.png" alt="schematics and sensors" /&gt;&lt;/p&gt;

&lt;h3 id="microcontroller"&gt;Microcontroller&lt;/h3&gt;

&lt;p&gt;I use the Boron microcontroller and set the device up through the company website. To receive data from the microcontroller itself, I connect it to my laptop via a USB cable. Microcontroller setup depends on which microcontroller you selected for use. Your microcontroller might provide other connection options, including Bluetooth or small server access over TCP/IP.&lt;/p&gt;

&lt;p&gt;Follow the instructions provided by your microcontroller’s manufacturer until you receive input from your sensors. You don’t need to make sense of the data yet; just make sure your microcontroller is sending raw data.&lt;/p&gt;

&lt;h3 id="influxdb"&gt;InfluxDB&lt;/h3&gt;

&lt;p&gt;Sign into InfluxDB. Create a bucket, which is where InfluxDB stores data. We will connect to InfluxDB via an API. The next step is to [create the required credentials and tokens]
(https://docs.influxdata.com/influxdb/v2.7/security/tokens/.&lt;/p&gt;

&lt;h3 id="code"&gt;Code&lt;/h3&gt;

&lt;p&gt;Writing data into InfluxDB is straightforward and starts with the client library. I use &lt;a href="https://docs.influxdata.com/influxdb/cloud/api-guide/client-libraries/python/"&gt;InfluxDB’s Python client library&lt;/a&gt; for this project. The code below is an example of how you can write code to send raw data from your microcontroller’s sensors to InfluxDB.&lt;/p&gt;

&lt;pre&gt;&lt;code class="language-sql"&gt;def write_to_influx(self,data):
	p = (influxdb_client.Point("sensor_data")
                    	.tag("user",data["user"])
                    	.tag("device_id",data["device"])                     
                    	.field(data["sensor_name"], int(data["value"])
                    	))
	self.write_api.write(bucket=self.cloud_bucket, org=self.cloud_org, record=p)
	print(p, flush=True)&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id="tags"&gt;Tags&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://docs.influxdata.com/influxdb/v1.3/concepts/key_concepts/"&gt;Measurements&lt;/a&gt; are the InfluxDB equivalent to tables in a relational database. My code makes good use of tags. Tags aren’t required but come in handy because they’re metadata that make the data easier to understand and work with. In this case they can specify different plants, devices or something else depending on how complicated you want to get.&lt;/p&gt;

&lt;h3 id="querying-data"&gt;Querying data&lt;/h3&gt;

&lt;p&gt;&lt;img src="//images.ctfassets.net/o7xu9whrs0u9/58ud1hFoNx2clv7tDcCjXa/709d55dba9a439b2afcf3d8570211530/quering_data.png" alt="quering data" /&gt;&lt;/p&gt;

&lt;p&gt;Queries return tables similar to the one below.&lt;/p&gt;

&lt;p&gt;Before I can query my data, I need to initialize the Flight SQL client.&lt;/p&gt;

&lt;pre&gt;&lt;code class="language-sql"&gt;from flightsql import FlightSQLClient&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Followed by:&lt;/p&gt;

&lt;pre&gt;&lt;code class="language-sql"&gt;# This is our flight client setup, it’s how we will query from IOX
    	# we need to remove the Https:// from our host
    	host = host.split("://")[1]
    	self.flight_client = FlightSQLClient(host=host,
                     	token=token,
                     	metadata= {'bucket-name': bucket}
        	             )

    	self.cloud_bucket = bucket
    	self.cloud_org = org&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Below is a basic SQL query to retrieve data from InfluxDB.&lt;/p&gt;

&lt;pre&gt;&lt;code class="language-sql"&gt;SELECT {sensor_name}, time FROM sensor_data WHERE time &amp;gt; (NOW() - INTERVAL '2 HOURS') AND device_id='{deviceID}'&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Before we can retrieve and read the data, we have to convert it to Pyarrow format. The code below is a function that includes the query and connection to Flight SQL to retrieve the data.&lt;/p&gt;

&lt;pre&gt;&lt;code class="language-sql"&gt;def querydata(self, sensor_name, deviceID) -&amp;gt; DataFrame:   	

        query = self.flight_client.execute(f"SELECT {sensor_name}, time FROM sensor_data WHERE time &amp;gt; (NOW() - INTERVAL '2 HOURS') AND device_id='{deviceID}'")

        # Create reader to consume result
    	reader = self.flight_client.do_get(query.endpoints[0].ticket)

    	# Read all data into a pyarrow.Table
    	Table = reader.read_all()
    	print(Table)

   	# Convert to Pandas DataFrame
    	df = Table.to_pandas()
    	df = df.sort_values(by="time")
    	print(df)
    	return df&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;You can call the previous query and substitute the variables for your selections, including bucket, sensor and device. The returned result allows you to graph your incoming data. The &lt;code class="language-sql"&gt;return df&lt;/code&gt; method pulls our data out in a data frame format.&lt;/p&gt;

&lt;h3 id="data-frames"&gt;Data frames&lt;/h3&gt;

&lt;p&gt;Pandas DataFrames are two-dimensional data structures that enable fast data analysis and processing. We convert our data to a DataFrame to make it easier to work with in Python. There are a few other data output options to choose from if you prefer a different style.&lt;/p&gt;

&lt;pre&gt;&lt;code class="language-sql"&gt;@app.callback(Output("store", "data"), [Input("button", "n_clicks")])
def generate_graphs(n):
# Generate graphs based upon pandas data frame. 
    df = influx.querydata( "soil_temperature", graph_default["deviceID"] )
    soil_temp_graph = px.line(df, x="time", y="soil_temperature", title="Soil Temperature")

    df = influx.querydata( "air_temperature", graph_default["deviceID"] )
    air_temp_graph= px.line(df, x="time", y="air_temperature", title="Air Temperature")

    df = influx.querydata( "humidity", graph_default["deviceID"] )
    humidity_graph= px.line(df, x="time", y="humidity", title="humidity")

    df = influx.querydata( "soil_moisture", graph_default["deviceID"] )
    soil_moisture= px.line(df, x="time", y="soil_moisture", title="Soil Moisture")

    df = influx.querydata( "light", graph_default["deviceID"] )
    light_graph= px.line(df, x="time", y="light", title="light")&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The graphing library expects you to return a dataframe for visualization. This is the end result of querying for the data points. The images below are hard-coded graphs that illustrate the data points. Different tabs display different graphs and track separate metrics. This is just a small portion of the project’s capabilities.&lt;/p&gt;

&lt;p&gt;&lt;img src="//images.ctfassets.net/o7xu9whrs0u9/LGkNALgV72zj2UQSnNJuy/5f7ca2f8f82ee506cb717c1b4942d2b8/Plant-Buddy-Dashboard.jpg" alt="Plant-Buddy-Dashboard" /&gt;&lt;/p&gt;

&lt;h2 id="conclusion"&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;Check out &lt;a href="https://www.socallinuxexpo.org/scale/20x/presentations/building-plant-monitoring-app-influxdb-python-and-flask-edge-cloud"&gt;my presentation&lt;/a&gt; centered around Plant Buddy for a more in-depth discussion on this project and the InfluxDB ecosystem at large. &lt;a href="https://github.com/InfluxCommunity"&gt;Our community page&lt;/a&gt; has other great examples of exciting projects. Now get started with InfluxDB and build something cool!&lt;/p&gt;
</description>
      <pubDate>Fri, 02 Jun 2023 07:00:00 +0000</pubDate>
      <link>https://www.influxdata.com/blog/build-plant-monitoring-tool-iot-beginner-friendly-tutorial/</link>
      <guid isPermaLink="true">https://www.influxdata.com/blog/build-plant-monitoring-tool-iot-beginner-friendly-tutorial/</guid>
      <category>Use Cases</category>
      <author>Zoe Steinkamp (InfluxData)</author>
    </item>
    <item>
      <title>Best Practices to Build IoT Analytics</title>
      <description>&lt;p&gt;&lt;em&gt;This article was originally published in &lt;a href="https://thenewstack.io/best-practices-to-build-iot-analytics/"&gt;The New Stack&lt;/a&gt; and is reposted here with permission.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Selecting the tools that best fit your IoT data and workloads at the outset will make your job easier and faster in the long run.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Today, Internet of Things (IoT) data or sensor data is all around us. Industry analysts project the number of  &lt;a href="https://www.influxdata.com/glossary/iot-devices/"&gt;connected devices&lt;/a&gt;  worldwide to be a total of 30.9 billion units by 2025, up from 12.7 billion units in 2021.&lt;/p&gt;

&lt;p&gt;When it comes to IoT data, keep in mind that it has special characteristics, which means we have to plan how to store and manage it to maintain the bottom line. Making the wrong choice on factors like storage and tooling can complicate data analysis and lead to increased costs.&lt;/p&gt;

&lt;p&gt;A single IoT sensor sends, on average, a data point per second. That totals over 80,000 data points in a single day. And some sensors generate data every nanosecond, which significantly increases that daily total.&lt;/p&gt;

&lt;p&gt;Most IoT  &lt;a href="https://www.influxdata.com/use-cases/iot/"&gt;use cases&lt;/a&gt;  don’t just rely on a single sensor either. If you have several hundred sensors, all generating data at these rates, then we’re talking about a lot of data. You could have millions of data points in a single day to analyze, so you need to ensure that your system can handle time series workloads of this size. Otherwise, if your storage is inefficient, your queries are slow to return, and if you don’t configure your analysis and visualization tools for this type of data, then you’re in for a bad time.&lt;/p&gt;

&lt;p&gt;In this article, I will go over six best practices to build efficient and scalable IoT analytics.&lt;/p&gt;

&lt;h2 id="start-your-storage-right"&gt;1. Start your storage right&lt;/h2&gt;

&lt;p&gt;Virtually all IoT data is  &lt;a href="https://www.influxdata.com/what-is-time-series-data/"&gt;time series data&lt;/a&gt;. Therefore, consider storing your IoT data in a time series database because, as purpose-built solutions for unique time series workloads, it provides the best performance. The shape of IoT data generally contains the same four components. The first is simply the name of what you’re tracking. We can call that a measurement, and that may be temperature, pressure, device state or anything else. Next are tags. You may want to use tags to add context to your data. Think about tags like metadata for the actual values you’re collecting. The values themselves, which are typically numeric but don’t have to be, we can call fields. And the last component is a timestamp that indicates when the measurement occurred.&lt;/p&gt;

&lt;p&gt;&lt;img src="//images.ctfassets.net/o7xu9whrs0u9/6mRI8FaxkR5vfZLz7eZq3S/d3db34fd9a8039331ca63b8ea615ad88/iot-analytics.JPG" alt="iot-analytics" /&gt;&lt;/p&gt;

&lt;p&gt;Knowing the shape and structure of our data makes it easier to work with when it’s in the database. So what is a time series database? It’s a database designed to store these data values (like metrics, events, logs and traces) and query them based on time. Compare this to a non-time series database, where you could query on an ID, a value type or a combination of the two. In a time series database, we query based entirely on time. As a result, you can easily see data from the past hour, the past 24 hours and any other interval for which you have data. A popular  &lt;a href="https://www.influxdata.com/time-series-database/"&gt;time series database&lt;/a&gt;  is  &lt;a href="https://www.influxdata.com/"&gt;InfluxDB&lt;/a&gt;, which is available in both cloud and open source.&lt;/p&gt;

&lt;h2 id="high-volume-ingestion"&gt;2. High-volume ingestion&lt;/h2&gt;

&lt;p&gt;Time series data workloads tend to be large, fast and constant. That means you need an efficient method to get your data into your database. For that we can look at a tool like  &lt;a href="https://www.influxdata.com/time-series-platform/telegraf/"&gt;Telegraf&lt;/a&gt;, an open source ingestion agent meant to run as a cron job to collect time series metrics. It has more than 300 plugins available for popular time series data sources, including IoT devices and more general plugins like execd, which you can use with a variety of data sources.&lt;/p&gt;

&lt;p&gt;Depending on the database you choose to work with, other data ingest options may include client libraries, which allow you to write data using a language of your choice. For instance, Python is a common option for this type of tool. It’s important that these client libraries come from your database source so you know they can handle the ingest stream.&lt;/p&gt;

&lt;h2 id="cleaning-the-data"&gt;3. Cleaning the data&lt;/h2&gt;

&lt;p&gt;You have three options when it comes to  &lt;a href="https://thenewstack.io/cleaning-and-interpreting-time-series-metrics-with-influxdb/"&gt;cleaning your data&lt;/a&gt;: You can clean it before you store it, after it’s in your database or inside your analytics tools. Cleaning up data before storage can be as simple as having full control over the data you send to storage and dropping data you deem unnecessary. Oftentimes, however, the data you receive is proprietary, and you do not get to choose which values you receive.&lt;/p&gt;

&lt;p&gt;For example, my light sensor sends extra device tags that I don’t need, and occasionally, if a light source is suddenly lost, it sends strange, erroneous values, like 0. For those cases, I need to clean up my data after storing it. In a database like InfluxDB, I can easily store my raw data in one data bucket and my cleaned data in another. Then I can use the clean data bucket to feed my analytics tools. There’s no need to worry about cleaning data in the tools, where the changes wouldn’t necessarily replicate back to the database. If you wait until the data hits your analytics tools to clean it, that can use more resources and affect performance.&lt;/p&gt;

&lt;h2 id="the-power-of-downsampling"&gt;4. The power of downsampling&lt;/h2&gt;

&lt;p&gt;Cleaning and downsampling data are not the same. Downsampling is aggregating the data based on time. For example, dropping a device ID from your measurement is cleaning, while deriving the mean value for the last five minutes is downsampling.  &lt;a href="https://www.influxdata.com/blog/tldr-influxdb-tech-tips-downsampling-flight-sql-aws-lambda/"&gt;Downsampling&lt;/a&gt;  is a powerful tool in that, like cleaning data, it can save you storage costs and make the data easier and faster to work with.&lt;/p&gt;

&lt;p&gt;In some cases, you can downsample before storing it in its permanent database, for example, if you know that you don’t need the fine-grained data from your IoT sensors. You can also use downsampling to compare data patterns, like finding the average temperature across the hours of the day on different days or devices. The most common use for downsampling is to aggregate old data.&lt;/p&gt;

&lt;p&gt;You monitor your IoT devices in real time, but what do you do with old data once new data arrives? Downsampling takes high-granularity data and makes it less granular by applying means, averages and other operations. This preserves the shape of your historical data so you can still do historical comparisons and anomaly detection while reducing storage space.&lt;/p&gt;

&lt;p&gt;&lt;img src="//images.ctfassets.net/o7xu9whrs0u9/25RkgKXmL8KM0XnM7SlOdX/d7b459ec8b0bde1111245af46bac1f60/iot-analytics-anomaly-detection.JPG" alt="iot-analytics-anomaly-detection" /&gt;&lt;/p&gt;

&lt;h2 id="real-time-monitoring"&gt;5. Real-time monitoring&lt;/h2&gt;

&lt;p&gt;When it comes to analyzing your data, you can either compare it to historical data to find anomalies, or you can set parameters. Regardless of your monitoring style, it’s important to do so in real time so that you can use the incoming data to make quick decisions and take fast action. The primary approaches for  &lt;a href="https://www.influxdata.com/use-cases/monitoring/"&gt;real-time monitoring&lt;/a&gt;  include using a built-in option in your database, real-time monitoring tools or a combo of the two.&lt;/p&gt;

&lt;p&gt;Regardless of the approach you choose, it’s critical for queries to have quick response times and minimal lag because the longer it takes for your data to reach your tools, the less real time it becomes. Telegraf offers output plugins to various real-time monitoring solutions. Telegraf is configured to work with time series data and is optimized for InfluxDB. So if you want to optimize data transport, you might want to consider that combination.&lt;/p&gt;

&lt;h2 id="historical-aggregation-and-cold-storage"&gt;6. Historical aggregation and cold storage&lt;/h2&gt;

&lt;p&gt;When your data is no longer relevant in real time, it’s common to continue to use it for historical data analysis. You might also want to store older data, whether raw or downsampled, in more efficient cold storage or a data lake. As great as a time series database is for ingesting and working with real-time data, it also needs to be a great place to store your data long term.&lt;/p&gt;

&lt;p&gt;Some replication across locations is almost inevitable, but the more you can prevent that, the better, outside of backups, of course. In the near future, InfluxDB will offer a dedicated cold storage solution. In the meantime, you can always use Telegraf output plugins to send your data to other cold storage solutions.&lt;/p&gt;

&lt;p&gt;When working with IoT data, it’s important to use the right tools, from storage to analytics to visualization. Selecting the tools that best fit your IoT data and workloads at the outset will make your job easier and faster in the long run.&lt;/p&gt;
</description>
      <pubDate>Mon, 01 May 2023 07:00:00 +0000</pubDate>
      <link>https://www.influxdata.com/blog/best-practices-build-iot-analytics/</link>
      <guid isPermaLink="true">https://www.influxdata.com/blog/best-practices-build-iot-analytics/</guid>
      <category>Use Cases</category>
      <author>Zoe Steinkamp (InfluxData)</author>
    </item>
    <item>
      <title>Cleaning and Interpreting Time Series Metrics with InfluxDB</title>
      <description>&lt;p&gt;&lt;em&gt;This article was originally published in &lt;a href="https://thenewstack.io/cleaning-and-interpreting-time-series-metrics-with-influxdb/"&gt;The New Stack&lt;/a&gt; and is reposted here with permission.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A look at how to use Flux for data cleansing and analytics through the browser and via Visual Studio.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Time series data is data you want to  &lt;a href="https://www.influxdata.com/time-series-analysis-methods/"&gt;analyze&lt;/a&gt;  and  &lt;a href="https://www.influxdata.com/solutions/application-performance-monitoring-apm/"&gt;monitor&lt;/a&gt;  over time. For example, you might want to know the water levels over the course of the day for a plant, or how much sunlight it receives and when. This is a simple but easy-to-understand example. Obviously on a larger scale the stakes can be higher. You could be monitoring server infrastructure in a data center or pressure of a machine on a factory floor.&lt;/p&gt;

&lt;p&gt;These are times when failure and  &lt;a href="https://www.influxdata.com/use-cases/real-time-analytics/"&gt;real-time&lt;/a&gt;  reactions can be extremely important to avoid an emergency.  &lt;a href="https://www.influxdata.com/what-is-time-series-data/"&gt;Time series data&lt;/a&gt;  is commonly metrics, normally from  &lt;a href="https://www.influxdata.com/glossary/iot-devices/"&gt;IoT devices&lt;/a&gt;  or server infrastructure.&lt;/p&gt;

&lt;p&gt;Metrics are normally data that arrives in a constant stream, a value every second, but sometimes it can be more random. Raw time series metrics data can benefit from cleanup and normalization before exposing it for broader use and storage. When dealing with large amounts of time series metrics, it can be helpful to standardize the ways in which others can search through that data for specific time frames using easy-to-understand tags. There are many types of time series metrics, but for this blog post, we will focus on metrics from our internal storage engine, provided by one of our site reliability engineers (SREs).&lt;/p&gt;

&lt;p&gt;&lt;img src="//images.ctfassets.net/o7xu9whrs0u9/1qpUYcyJvkV0wHjwqxRIys/6c5e0d3f997e8e40971129bd9225c36d/physica-vs-virtual.png" alt="physica-vs-virtual" /&gt;&lt;/p&gt;

&lt;p&gt;For this tutorial, I will use  &lt;a href="https://www.influxdata.com/"&gt;InfluxDB&lt;/a&gt;’s time series data platform. The core of InfluxDB is a highly performant time series database that is great when processing millions of data per seconds, but it also comes with data collectors and scripting languages. This technical session focuses on using  &lt;a href="https://www.influxdata.com/products/flux/"&gt;Flux&lt;/a&gt;, a data-processing and querying language used by InfluxDB. Flux has many of the capabilities of a query language like SQL, but it also comes prebuilt with analyzation and data science capabilities. Later, we will also use Flux to create alerts and downsample tasks. In the future we will also include SQL integration, which will allow for a new way to query your data.&lt;/p&gt;

&lt;p&gt;Flux is already built into Influx, so there is no need for extra installation. Examples of how to leverage Flux for data cleansing and analytics through the browser and via Visual Studio will be demonstrated. You can check out the Visual Studio extension  &lt;a href="https://docs.influxdata.com/influxdb/cloud/tools/flux-vscode/"&gt;here&lt;/a&gt;  for more details. But you can also use the command line or the cloud UI to interact with your data.&lt;/p&gt;

&lt;p&gt;&lt;img src="//images.ctfassets.net/o7xu9whrs0u9/1phjpZhT8hGxlPgZaxh4bE/c5cd1e1cae5ae4e650c68ee43cbca367/flux.png" alt="flux" /&gt;&lt;/p&gt;

&lt;p&gt;We will start with a simple Flux query to get more familiar with how Flux is written and works. Your bucket is your database name. Each bucket can be customized on that data it accepts and the length of time it retains that data. First notice the  &lt;a href="https://docs.influxdata.com/flux/v0.x/stdlib/universe/range/"&gt;range() function&lt;/a&gt;. Since this language is for time series, logically we need to query for data from a time range. In this example our range is about 20 seconds (from the start and stop times). You could choose to have no range, but that will return all the data in your bucket.&lt;/p&gt;

&lt;p&gt;This is data from our measurement called “node_points_total.” It has a set of counters, which increment every time a point gets written. If it’s a good point, the “ok” gets incremented; if it’s a “bad” point, the corresponding point gets incremented. Here we’re calculating the total number of points that were successfully written. The top of the function is filtering down to a specific node and host we want to monitor. We search for points with four statuses (ok, denied, error and dropped). Then we pivot the data and calculate the percent that were ok with the  &lt;a href="https://docs.influxdata.com/flux/v0.x/stdlib/universe/map/"&gt;map() function&lt;/a&gt;. The  &lt;code&gt;map()&lt;/code&gt;  function generates a “percentage good” number, which will allow you to say “99.98% of all points written were OK.”&lt;/p&gt;

&lt;p&gt;&lt;img src="//images.ctfassets.net/o7xu9whrs0u9/1XBlzKib9jq1nEEER3qUkQ/64bfec15eb22a2d726a3b848d2774369/import-universe.png" alt="import-universe" /&gt;&lt;/p&gt;

&lt;p&gt;This is the result from the query being run. As you can see, we are visualizing the result.&lt;/p&gt;

&lt;p&gt;&lt;img src="//images.ctfassets.net/o7xu9whrs0u9/2gq8dvMxfWNaKYLMs7WqCk/38635cc7dcc4c3ba0943ba285acc00ae/singlge_percent.png" alt="singlge percent" /&gt;&lt;/p&gt;

&lt;p&gt;The next example is going to use a larger range, four days of data. That’s a lot! We are using an  &lt;a href="https://docs.influxdata.com/flux/v0.x/stdlib/universe/aggregatewindow/"&gt;aggregateWindow()&lt;/a&gt;  that will give us the sum of our values for every hour (we will return 96 results, one for each hour of the past four days). This is not only a faster query, but if we were to look at the data result in a table, it would also be easier to read only 96 results instead of 2 million!&lt;/p&gt;

&lt;p&gt;&lt;img src="//images.ctfassets.net/o7xu9whrs0u9/ObpVj0lD8aB6yEa8g4ocj/778cead7b5a2b18e53178ad916da8a16/import-universe-2.png" alt="import-universe-2" /&gt;&lt;/p&gt;

&lt;p&gt;This is the last query graphed. Here we see a small drop at 99.88% “ok” writes over the span of a few days. Our service-level agreement (SLA) for cloud is 99.9% monthly availability. But this is an example of a specific day that had a small incident. Overall, we still meet our SLA goals, but it may be good to notice even minor dips. This allows our SRE team to take action when needed.&lt;/p&gt;

&lt;p&gt;&lt;img src="//images.ctfassets.net/o7xu9whrs0u9/77fBg2q4OajTQpWqCFMbE2/9d11e5dbcc63e9e9a8d753ae8325ffe9/Percent_Ok_over_time_with_aggregateWindow.png" alt="Percent Ok over time with aggregateWindow" /&gt;&lt;/p&gt;

&lt;p&gt;This following Flux is a simplified version of what we call downsampling. Downsampling is the process of reducing raw high-precision data to lower precision aggregates. We combine the use of the  &lt;a href="https://docs.influxdata.com/flux/v0.x/stdlib/universe/aggregatewindow/"&gt;aggregateWindow() function&lt;/a&gt;  with the  &lt;a href="https://docs.influxdata.com/flux/v0.x/stdlib/influxdata/influxdb/to/"&gt;to() function&lt;/a&gt;  to write the downsampled data to a new bucket. In this example, we get the mean value for every 10-minute interval of data and store that data point in a new bucket.&lt;/p&gt;

&lt;p&gt;This can be helpful for three problems:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Making it easier to run analysis on a smaller data set and gain high-level insights from historical data.&lt;/li&gt;
  &lt;li&gt;Leaning up erroneous data.&lt;/li&gt;
  &lt;li&gt;Storing a smaller data set for the long term and reducing your overall instance size while retaining the overall shape of your data.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;img src="//images.ctfassets.net/o7xu9whrs0u9/5SRc8p8SD6Cr01ViYaBS4G/f4113b4646960010ed68bd8b2fc0b998/214eda18-image7-e1677270704151.png" alt="new bucket" /&gt;&lt;/p&gt;

&lt;p&gt;Finally we will take a look at alerting on our data set. This first part is all about filtering down to the field we want to monitor. We specifically want to filter for the “ok” status.&lt;/p&gt;

&lt;p&gt;&lt;img src="//images.ctfassets.net/o7xu9whrs0u9/4v66YqPkCqAPVfojG9dAvD/32059ed28f1e77ab434c7bdcea21f83b/alerting_on_our_data_set.png" alt="alerting on our data set" /&gt;&lt;/p&gt;

&lt;p&gt;We are using the  &lt;a href="https://docs.influxdata.com/flux/v0.x/stdlib/experimental/quantile/"&gt;quantile function&lt;/a&gt;  to determine when a value is outside the 95th percentile (95p). The compression in our quantile compression is how detailed we would want the data to be when determining the 95p. The larger the compression, the slower it would take to calculate. You can find more information in the docs in how to set up the quantile function.&lt;/p&gt;

&lt;p&gt;This code is checking that value and setting the type and level to “critical” or “info.” From there we also create a Slack message that sends an alert if the status type is “critical.” We have an alert function here that is being called, but it’s not needed to go in depth on it. The bottom line is you can use Flux to build these alert tasks and receive alerts if your data is out of a defined boundary or is doing OK. To learn more about creating alerts and notifications with Flux, take a look at the following  &lt;a href="https://docs.influxdata.com/influxdb/cloud/monitor-alert/"&gt;documentation&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;img src="//images.ctfassets.net/o7xu9whrs0u9/5FvZVqwFyQJaBJH226Kbrr/4289623911a9619f7c8ce28d5715e126/creating_alerts_and_notifications_with_Flux.png" alt="creating alerts and notifications with Flux" /&gt;&lt;/p&gt;

&lt;p&gt;These are just a few of the simpler capabilities for cleaning and interpreting your time series metrics in InfluxDB. We have a large amount of &lt;a href="https://docs.influxdata.com/flux/v0.x/"&gt;Flux documentation&lt;/a&gt; and examples you can reference depending on your use case and needs. We love to see what people are building in our &lt;a href="https://community.influxdata.com/"&gt;open source community&lt;/a&gt; and look forward to connecting with you in our community forums and Slack channel to see what amazing projects you build!&lt;/p&gt;
</description>
      <pubDate>Fri, 31 Mar 2023 07:00:00 +0000</pubDate>
      <link>https://www.influxdata.com/blog/cleaning-interpreting-time-series-metrics-influxdb/</link>
      <guid isPermaLink="true">https://www.influxdata.com/blog/cleaning-interpreting-time-series-metrics-influxdb/</guid>
      <category>Developer</category>
      <author>Zoe Steinkamp (InfluxData)</author>
    </item>
    <item>
      <title>Data Visualizations with InfluxDB: Integrating plotly.js</title>
      <description>&lt;p&gt;One of the great features of the InfluxData cloud platform is that it comes out of the box with all the tools you need to quickly read and write your data to the database. Here, we’ll walk through creating data visualizations with InfluxDB and &lt;a href="https://plot.ly/"&gt;plotly.js&lt;/a&gt;, a JavaScript graphing library built on top of &lt;a href="https://d3js.org/"&gt;d3.js&lt;/a&gt; and &lt;a href="http://stack.gl/"&gt;stack.gl&lt;/a&gt;. (If you’re instead looking for a tutorial on &lt;a href="https://www.influxdata.com/blog/visualizing-time-series-data-chartjs-influxdb/"&gt;visualizing time series data with Chart.js and InfluxDB&lt;/a&gt;, click the link.)&lt;/p&gt;

&lt;h2&gt;Getting started&lt;/h2&gt;
&lt;p&gt;Before we start visualizing, we need to set up an instance of InfluxDB on our local machines. When you create your account on &lt;a href="https://www.influxdata.com/"&gt;Influx&lt;/a&gt; you will want to create a bucket you can store your time series data inside and pull from. When you have your bucket you can go to the /client-libraries/javascript-node page and you can grab a token that is valid to read and write your bucket. You will also find examples on how to install, setup, and query on this page.&lt;/p&gt;

&lt;p&gt;&lt;img class="aligncenter wp-image-262283" src="/images/legacy-uploads/Set-up-InfluxDB.png" alt="Set up InfluxDB" width="980" height="248" /&gt;&lt;/p&gt;
&lt;h2&gt;Querying data from InfluxDB&lt;/h2&gt;
&lt;p&gt;When you start your project you will want to run these commands, this will initialize the node project, install the influx client and install express.&lt;/p&gt;
&lt;pre class="line-numbers"&gt;&lt;code class="language-bash"&gt;npm init -y influx-node-app
npm i @influxdata/influxdb-client
npm install express --save&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Once you’re all set up, and InfluxDB is running, you can set up a file to query the database and grab some data. I’m going to do this with Node/Express using the &lt;a href="https://github.com/influxdata/influxdb-client-js"&gt;influx-js client library&lt;/a&gt;. For this example, I’ll be querying for data that Telegraf is already collecting for my computer. If you have the &lt;a href="https://www.influxdata.com/get-influxdb/"&gt;Telegraf&lt;/a&gt; installed and running, you should be able to do the same. I would expect your package.json file to look like this, keeping in mind i have my main file as app.js:&lt;/p&gt;

&lt;p&gt;&lt;img class="aligncenter wp-image-262279" src="/images/legacy-uploads/package-json-file.png" alt="package.json file" width="980" height="601" /&gt;&lt;/p&gt;

&lt;p&gt;In my app.js file, I have the following. As you can see you will need to add your org email and your secret token, it will need to be added to a token file that you don’t push up to GitHub publicly. Also pay attention to what your influx url is, mine is set to us-west:&lt;/p&gt;

&lt;p&gt;&lt;img class="aligncenter wp-image-262281" src="/images/legacy-uploads/add-email-and-token.png" alt="add email and token" width="980" height="262" /&gt;&lt;/p&gt;

&lt;p&gt;Finally in the rest of my app.js file:&lt;/p&gt;

&lt;p&gt;&lt;img class="aligncenter wp-image-262274" src="/images/legacy-uploads/app-get-function-to-grab-cpu-total-usage.png" alt="app-get function to grab cpu total usage" width="980" height="735" /&gt;&lt;/p&gt;

&lt;p&gt;This is my app.get function to grab my cpu total usage. I am using a flux query with a few filter functions to get the exact data I’m looking to display. I am filtering down with my flux query because it is easier to filter the data coming in then do filter in our application. My flux query was built using the query builder in the InfluxDB Cloud. This made it easy to build my simple query and then by switching to script editor I could copy the flux script.&lt;/p&gt;

&lt;p&gt;&lt;img class="aligncenter wp-image-262277" src="/images/legacy-uploads/flux-query-2.png" alt="flux query" width="980" height="442" /&gt;&lt;/p&gt;

&lt;p&gt;From there, the data is called into our script.js file.&lt;/p&gt;

&lt;p&gt;&lt;img class="aligncenter wp-image-262280" src="/images/legacy-uploads/the-data-is-called-into-our-script-js-file.png" alt="the data is called into our script.js file" width="980" height="938" /&gt;&lt;/p&gt;

&lt;p&gt;Here I have two fetch functions that call for two specific data sources with two separate Flux queries. We unpack the data and specifically we are looking for the time and value to be our x and y lines when graphed. We return trace data which is our graph with an array of x and y variables. Finally once we have received all the data from influx and prepared our graph object we call for Plotly to be graphed.&lt;/p&gt;

&lt;p&gt;&lt;img class="aligncenter wp-image-262276" src="/images/legacy-uploads/fetchData-function.png" alt="fetchData function" width="980" height="252" /&gt;&lt;/p&gt;

&lt;p&gt;It’s important if you add more fetch data calls that you add them to our promise so it waits to make the Plotly graphs until all the data has been returned. And finally we make our Plotly line graph with two lines.&lt;/p&gt;
&lt;h2&gt;&lt;img class="aligncenter wp-image-262282" src="/images/legacy-uploads/call-for-plotly.png" alt="call for plotly" width="980" height="229" /&gt;&lt;/h2&gt;
&lt;h2&gt;Setting up HTML and CSS&lt;/h2&gt;
&lt;p&gt;In the public folder directory you will find the index.html, styles.css, and scripts.js file. We will be using these files to display the plotly graphs. In our index.html you will see where we append the graph from script.js:&lt;/p&gt;

&lt;p&gt;&lt;img class="aligncenter wp-image-262284" src="/images/legacy-uploads/Setting-Up-HTML-and-CSS.png" alt="Setting Up HTML and CSS" width="980" height="565" /&gt;&lt;/p&gt;

&lt;p&gt;Aside from incorporating jquery and your script file, you’ll need to incorporate the Plotly CDN. Alternatively, you can install the plotly.js library as an npm module. For more information on that, please visit the &lt;a href="https://plot.ly/javascript/getting-started/"&gt;“Getting Started” guide&lt;/a&gt; on the plotly.js website.&lt;/p&gt;

&lt;p&gt;Let’s add the following CSS to our styles.css file for a bit of flair:&lt;/p&gt;

&lt;p&gt;&lt;img class="aligncenter wp-image-262285" src="/images/legacy-uploads/css-styles-1.png" alt="css-styles" width="450" height="1406" /&gt;&lt;/p&gt;

&lt;p&gt;If you restart your server at this point and navigate to localhost:3000, you should see something similar to this:&lt;/p&gt;

&lt;p&gt;&lt;img class="aligncenter wp-image-262278" src="/images/legacy-uploads/Graph-Local-CPU-Usage.png" alt="Graph: Local CPU Usage" width="980" height="535" /&gt;&lt;/p&gt;

&lt;p&gt;And voila! You’ve got yourself a custom time series visualization, using InfluxDB and plotly.js! You can check out the source code on &lt;a href="https://github.com/InfluxCommunity/PlotlyJavascript"&gt;GitHub&lt;/a&gt; or feel free to ping me an email at &lt;a href="mailto:zsteinkamp@influxdb.com"&gt;zsteinkamp@influxdb.com&lt;/a&gt;.&lt;/p&gt;
</description>
      <pubDate>Sat, 29 Jan 2022 13:31:43 -0700</pubDate>
      <link>https://www.influxdata.com/blog/data-visualizations-with-influxdb-integrating-plotly-js/</link>
      <guid isPermaLink="true">https://www.influxdata.com/blog/data-visualizations-with-influxdb-integrating-plotly-js/</guid>
      <category>Product</category>
      <category>Use Cases</category>
      <category>Developer</category>
      <author>Zoe Steinkamp (InfluxData)</author>
    </item>
  </channel>
</rss>
