New tool RC:
REQUIRES 2025.6.x or better (recorder.get_statistics)
History CRUD - because someone went and made recorder.get_statistics and I could not be happier…
Yep it’s exactly what it say s it is - AI access to the history stats.
NOW - WARNING - this one’s a tool that’s a LOT open ended, it’s prerelease so the docs suck and - yes there are surprises. It will not be 100% but shouldn’t be destructive. I handled attempts to create, edit or delete history.
YOU WILL have to walk the LLM through creating the report you want, but if you know what’s in the db and your stats are actually there - she can see them. ![]()
*chuckle h-Back… STT HATES HVAC with my voice, fortunately Friday tolerates it…
Now if I only had a way of saving the report spec… ![]()
(But that’s another show)
and, yes the repo is almost up. But I was working on a string of tool updates that honestly you reeeeeeeally want. So let me finish that refactor first.
History CRUD (YES they’re getting a new name soon)
Now with 100% more timelord:
alias: history CRUD (1.0.2-RC)
mode: parallel
fields:
action_type:
name: CRUD Action
required: true
default: help
selector:
select:
options:
- read
- create
- update
- delete
- help
statistic_ids:
description: List of sensor/statistic IDs to query
selector:
entity:
multiple: true
required: true
start_time:
description: ISO 8601 UTC timestamp
selector:
datetime: {}
end_time:
description: ISO 8601 UTC timestamp
selector:
datetime: {}
period:
description: Time grouping (5minute, hour, day, week, month)
default: hour
selector:
select:
options:
- 5minute
- hour
- day
- week
- month
types:
description: List of statistical types to return (mean, sum, etc.)
selector:
select:
multiple: true
options:
- change
- last_reset
- max
- mean
- min
- state
- sum
name: types
units:
description: >-
Optional unit conversion map (e.g. {"energy": "kWh"}); use if you need an
output conversion such as Wh to kWh...
selector:
object: {}
context:
description: Optional label for trace/logging
selector:
text: {}
sequence:
- variables:
error_msgs: >-
{%- set msgs = [] -%}
{%- if statistic_ids is not defined or statistic_ids is none or
statistic_ids == '' or statistic_ids == [] -%}
{%- set _ = msgs.append("Missing required field: statistic_ids") -%}
{%- endif -%}
{%- if action_type == 'read' and (types is not defined or types is none
or types == '' or types == []) -%}
{%- set _ = msgs.append("Missing required field: types") -%}
{%- endif -%}
{{ msgs }}
error_flag: "{{ error_msgs|count > 0 }}"
query_payload: |-
{% set q = {"statistic_ids": statistic_ids} %} {% set q = q | combine(
start_time is defined and start_time != None and {"start_time": start_time} or {},
end_time is defined and end_time != None and {"end_time": end_time} or {},
period is defined and period != None and {"period": period} or {},
types is defined and types and {"types": types} or {},
units is defined and units and {"units": units} or {},
recursive=True
) %} {{ q | to_json }}
help_sample_outdoor: sensor.home_thermostat_outdoor_temperature
help_sample_main_panel_consumption: sensor.main_panel_daily_consumption
help_text:
help: true
action: read
errors: "{{ error_msgs if error_flag else none }}"
usage_notes:
- Use 'read' to access historical statistics.
- >-
Only 'read' is supported. Other actions return structured errors.
It's History...
- Specify sensor or statistic IDs to analyze.
- Provide ISO start and end timestamps for range.
- Select period grouping (daily, hourly, monthly, etc.).
- Pick statistics types to return (mean, max, min, sum, etc.).
- Data is returned grouped by period for trend analysis.
- Retry or adjust parameters if data missing.
- Works best on continuous numeric sensors with stats enabled.
- Timezone-aware to ensure accurate day boundaries.
- Can query multiple sensors simultaneously.
- Useful for spotting usage patterns and anomalies.
fields_reference:
required_fields:
- statistic_ids
optional_fields:
- start_time
- end_time
- period
- types
- units
- context
statistic_ids: List of entity statistic_ids to query (sensor.*)
start_time: Start of the query range (ISO8601 format)
end_time: End of the query range (ISO8601 format)
period: Aggregation interval (5minute, hour, day, week, month)
types: Types of statistics to fetch (mean, min, max, sum, state)
cheat_sheet:
description: >
This cheat sheet provides structured guidance for using the
`recorder.get_statistics` service in Home Assistant to query
historical statistics data from the built-in database.
example_use_cases:
- id: daily_temp_summary
description: >
Get average daily temperature from a specific sensor for a time
period. Uses the authoritative outdoor temp sensor if availabe
(not null).
statistic_ids: "{{ help_sample_outdoor }}"
start_time: "2025-06-01T00:00:00"
end_time: "2025-06-08T00:00:00"
period: day
types:
- mean
- id: daily_energy_usage_since_date
description: >
Retrieve daily total energy consumption for a main panel
consumption since 1 Apr 2025. Note this sensor is 'always
increasing' (from the class) so we use 'change' to get accurate
daily use. Uses the authoritative omain consumptionsensor if
available (not null).
statistic_ids: "{{ help_sample_main_panel_consumption }}"
start_time: "2025-04-01 00:00:00"
period: day
types:
- change
units:
Wh: kWh
notes:
- >-
the samples were provided for 'known good' references. We
understand that 'no data' is generally acceptable from this tool
The sample cases were provided to show good example cases and
indicate REAL entites in this installation. If you try them and
they DO NOT return data something may be in error.
- >-
Only sensors with long-term statistics enabled will return data.
Some sensors just don't have it... If we should turn on
statistics for a specific reason suggest so.
- >-
Use 'change' to get the delta between start and end - the actual
usage for period on always increasing sensors (most energy and
water sensors) if the numbers seem absolutely absurd (as in
millions of kWh, for instance) you probably got hold of an always
increasing sensor and need to get the db to do the math for you.
source:
- https://www.home-assistant.io/integrations/recorder/#statistics
- https://www.home-assistant.io/integrations/statistics/
- choose:
- conditions:
- alias: ERROR - Required fields missing
condition: template
value_template: "{{ action_type == 'read' and error_flag }}"
sequence:
- variables:
history_result: "{{ help_text }}"
- stop: "Read error: Required fields missing"
response_variable: history_result
- conditions:
- condition: template
value_template: "{{ action_type == 'read' }}"
alias: READ
sequence:
- action: recorder.get_statistics
data: "{{ query_payload }}"
response_variable: history_result
- stop: Read complete
response_variable: history_result
- conditions:
- condition: template
value_template: "{{ action_type == 'create' }}"
alias: CREATE
sequence:
- variables:
history_result:
error: true
code: H-0001
reason: Temporal Paradox
detail: You cannot create history. You are not the Doctor.
- stop: Create complete
response_variable: history_result
- conditions:
- condition: template
value_template: "{{ action_type == 'delete' }}"
alias: DELETE
sequence:
- variables:
history_result:
error: true
code: H-0002
reason: Redaction Denied
detail: This isn’t a reality show. You don’t get to delete the past.
- stop: Delete complete
response_variable: history_result
- conditions:
- condition: template
value_template: "{{ action_type == 'update' }}"
alias: UPDATE
sequence:
- variables:
history_result:
error: true
code: H-0003
reason: Zen Violation
detail: >
You cannot rewrite history. You can, however, learn from it.
See: https://www.goodreads.com/quotes/tag/change
- stop: Update complete
response_variable: history_result
- conditions:
- condition: template
value_template: "{{ action_type == 'help' }}"
alias: HELP
sequence:
- variables:
history_result: "{{help_text}}"
- stop: Help complete
response_variable: history_result
description: |-
History Stats for Homeassistant
Uses recorder.get_statistics for current entity stats.
Beta
Nest update planned target by label
Read HELP for detailed use
See HELP - cheat_sheet for detailed usage instructions and examples.
Also this is the new default pattern if anyone sees refinement please chime in. I’m not building for pretty I’m building for
AI tool use first (document the hell out of it, self descriptive, confirm null returns json safe descriptive, context rich with pointers and help.)
