How to duration between two status changes?

I'm wondering how I would get the duration how long something ran? For example the time when the hvac ran the ac (cooling) and when it stopped (idle). My goal is to keep them and eventually have weekly, monthly and seasonal history to compare with among other metrics.

I just recently starting using elastic and kibana with Home Assistant. Any guidance is appreciated or links to resources or other topics with Home Assistant and Kibana. Thank you.

Hi @vincenty79,

Welcome to the Elastic community. You need to transform your data, Which will eventually create a entity centric index by calculating elapsed time.

Here is the quick example align to your use case

# Create an ingest pipeline to add timestamp into documents. Feel free to skip this in your =case.
PUT _ingest/pipeline/add_date
{
  "description" : "This pipeline add the ingest time to the document",
  "processors" : [
    {
      "set" : {
        "field": "received",
        "value": "{{_ingest.timestamp}}"
      }
    }
  ]
}

# Add some documents
POST source_index/_doc?pipeline=add_date
{
  "home_id":1,
  "status": "idle"
}

POST source_index/_doc?pipeline=add_date
{
  "home_id":1,
  "status": "cooling"
}

POST source_index/_doc?pipeline=add_date
{
  "home_id":2,
  "status": "idle"
}

POST source_index/_doc?pipeline=add_date
{
  "home_id":2,
  "status": "cooling"
}


GET source_index/_search


# create a transform
PUT _transform/calc-duration
{ 
  "source": {
    "index": "source_index"
  },
  "pivot": {
    "group_by": {
      "home": {
        "terms": {
          "field": "home_id"
        }
      }
    },
    "aggregations": {
      "idle": {
        "filter": {
          "term": {
            "status": "idle"
          }
        },
        "aggs": {
          "min_time": {
            "min": {
              "field": "received"
            }
          }
        }
      },
      "cooling": {
        "filter": {
          "term": {
            "status": "cooling"
          }
        },
        "aggs": {
          "max_time": {
            "max": {
              "field": "received"
            }
          }
        }
      },
      "duration": {
        "bucket_script": {
          "buckets_path": {
            "min": "idle>min_time",
            "max": "cooling>max_time"
          },
          "script": "(params.max - params.min) / 1000"
        }
      }
    }
  },
  "dest": {
    "index": "source_index_transformed"
  },
  "sync": {
    "time": {
      "field": "received",
      "delay": "10s"
    }
  }
}

# start transform, It will sync in every 10 seconds
POST _transform/calc-duration/_start

# Get your summarize result
GET source_index_transformed/_search

Wow thank you so much. It seems overwhelming but this is a perfect opportunity for me to learn more. I appreciate you taking the time to write up an answer and including links to what transform and centric index is.

1 Like