How to send monthly energy report using notifications (but not at midnight)

I have setup a utility meter with two different tariffs and two input numbers with the energy rates (which I update manually every quarter); I have also setup a template sensor that calculates the total energy cost for the current month combining the two tariffs.
I now want to send a mobile notification at the end of the month, but I don’t want to send it at midnight, but rather some time during the next day (let’s say at 9).
Note that since I’m using a template sensore for the monetary total, it doesn’t have the “previous period” attribute. Do I need to setup an additional utility meter sensor that uses the template sensor as an input or is there a better way?

So you want to send a message on the first day of the month at 9am but by then the utility meters (and hence your total cost sensor) have rolled over into the next cycle?

The easiest way I can think of would be to store the total with a triggered sensor just before midnight on the last day of the month.

template:
  - trigger:
      - platform: template
        value_template: "{{ (as_timestamp(now()) + 86400)|timestamp_custom('%d', true) == 01 and now().hour == 23 and now().minute == 59 }}"
    sensor:
      - name: Last Month Total Energy Cost
        state: "{{ states('sensor.your_total_energy_cost_sensor_here') }}"

The template triggers at 23:59 on the last day of the month (found by adding a day to now() and checking if tomorrow is the 1st) and stores your total in another sensor for later use in an automation with a time trigger at 9am.

EDIT: do not be tempted to check for now().seconds == 59 as well, for greater accuracy. The template will only trigger every minute.

Thank you very much, does this piece of code need to be inside an automation or in the configuration file under sensors?

Just in the configuration.yaml file. It is the new way of defining tempate sensors.

See: Template sensor

trying the template in developer tools suggests I need quotes around the day of the month, but the config check suggests I need to remove them (exactly how you’ve posted the code), why is that?

EDit: despite the config check working, I get this error after restart

Logger: homeassistant.config
Source: config.py:443
First occurred: 5:26:37 PM (1 occurrences)
Last logged: 5:26:37 PM

Invalid config for [template]: invalid template (TemplateSyntaxError: expected token 'end of print statement', got 'integer') for dictionary value @ data['value_template']. Got None. (See ?, line ?).

It’s the same that I get in developer tools

Missing quotes. Try this:

value_template: "{{ (as_timestamp(now()) + 86400)|timestamp_custom('%d', true) == '01' and now().hour == '23' and now().minute == '59'  }}"

The 01 needs quotes because the result of timestamp_custom is a string. However, the other two values, 23 and 59 should not be quoted because the reported hour and minute are integers.

Here’s a slightly shorter version where all three values are integers:

value_template: "{{ (now() + timedelta(days=1)).day == 1 and now().hour == 23 and now().minute == 59 }}"
1 Like

Thanks Taras, I originally wrote that template before we had access to timedelta(). Another good update.

This has been working, provided I don’t restart HA between midnight and 9am. If I do, the values return the value “unknown” after the restart; I would also like to retain the values until next month for convenience and it’s likely I’ll restart HA at least one in once month.

Is there a way to retain the values after a restart?

What would be the syntax for the new modern style?

I tried this but have an error…
Invalid config for [template]: [trigger] is an invalid option for [template]. Check: template->sensor->0->trigger. (See /config/configuration.yaml, line 453).

image


image

That is the template integration, not the older template sensor platform.

It does not go in your sensor.yaml file.

If goes in your configuration.yaml file just like any other integration.

I am already using !include for template:

image

I tried this…

image

  - trigger:
      - platform: template
        value_template: "{{ (now() + timedelta(days=1)).day == 1 and now().hour == 23 and now().minute == 59 }}"
    sensor:
      - name: Last Month Total Energy Cost
        state: "{{ states('sensor.node_50_electric_consumed_kwh') }}"

But I have this error…

Logger: homeassistant.config
Source: config.py:454
First occurred: 10:35:58 AM (2 occurrences)
Last logged: 10:43:38 AM

Invalid config for [template]: required key not provided @ data['trigger'][0]['platform']. Got None. (See /config/configuration.yaml, line 453).

It appears I am screwed? In order to segregate binary_sensor, select and sensor templates, I have a templates folder with files named appropriately in which template: and - binary_sensor: etc. are not needed as those lines occur as a result of the include. However, I cannot seem to format trigger: properly using the same technique in a trigger.yaml…

You just need to use !include_dir_merge_list

The template integration has a list of sensors under it.

You use dir_merge_named for integrations that take dictionaries. Like the input_number integration.

List

some_key:
  - something: value
  - something: value
  - something: value

Dictionary:

some_key:
  something: value
  something: value
  something: value

Thanks Tom for the insight!
I managed after posting and before reading your answer to do it this way…

template:
  - trigger:
    - platform: template
      value_template: "{{ (now() + timedelta(days=1)).day == 1 and now().hour == 23 and now().minute == 59 }}"
    sensor:
      - name: Last Month Car Charging Total Energy Cost
        state: "{{ states('sensor.node_50_electric_consumed_kwh') }}"

  - trigger:
    - platform: time_pattern
      seconds: "/5"
    sensor:
      - name: HASS Agent My PC Idle Time
        state: '{{ as_timestamp(utcnow()) - as_timestamp(states("sensor.lastactive")) }}'
        unit_of_measurement: "Seconds"
        
# Example configuration entry
  - trigger:
    - platform: time_pattern
      # This will update every night
      hours: 0
      minutes: 0
    sensor:
      # Keep track how many days have past since a date
      - name: "Not smoking"
        state: '{{ ( ( as_timestamp(now()) - as_timestamp(strptime("06.07.2018", "%d.%m.%Y")) ) / 86400 ) | round(default=0) }}'
        unit_of_measurement: "Days"

template includes: !include_dir_named templates/

Revised:

#template:
#  - trigger:
#    - platform: template
#      value_template: "{{ (now() + timedelta(days=1)).day == 1 and now().hour == 23 and now().minute == 59 }}"
#    sensor:
#      - name: Last Month Car Charging Total Energy Cost
#        state: "{{ states('sensor.node_50_electric_consumed_kwh') }}"
#
#  - trigger:
#    - platform: time_pattern
#      seconds: "/5"
#    sensor:
#      - name: HASS Agent My PC Idle Time
#        state: '{{ as_timestamp(utcnow()) - as_timestamp(states("sensor.lastactive")) }}'
#        unit_of_measurement: "Seconds"
#        
## Example configuration entry
#  - trigger:
#    - platform: time_pattern
#      # This will update every night
#      hours: 0
#      minutes: 0
#    sensor:
#      # Keep track how many days have past since a date
#      - name: "Not smoking"
#        state: '{{ ( ( as_timestamp(now()) - as_timestamp(strptime("06.07.2018", "%d.%m.%Y")) ) / 86400 ) | round(default=0) }}'
#        unit_of_measurement: "Days"
#
#template includes: !include_dir_named templates/
template: !include_dir_merge_list templates/

image

I had to add binary_sensor:, select: and sensor: to my existing files…

Again, thanks for the insight!

Now my binary_sensors, sensor and select’s are broken… Only the 1st entity is created, the rest are unavailable/‘restored’.
With your config, are you specifying binary_sensor: etc. for each template entity?

binary_sensor:    
  - name: Close to Home
    state: '{{ states("proximity.home")|int < states("input_number.close_to_home_trigger")|int }}'

  - name: Night Mode
    unique_id: night_mode
    availability: '{{ not is_state("sensor.south_patio_illuminance_lux", "unavailable") }}'
    state: '{{ states("sensor.south_patio_illuminance_lux")|float(default=0) < states("input_number.outside_lux_trigger_point")|float(default=0) }}'
    delay_on: 00:02:00
    delay_off: 00:01:00
    
  - name: Living Room Night Mode
    unique_id: living_room_night_mode
    availability: '{{ not is_state("sensor.south_patio_illuminance_lux", "unavailable") }}'
    state: '{{ states("sensor.south_patio_illuminance_lux")|float(default=0) < states("input_number.living_room_lux_trigger_point")|float(default=0) }}'
    delay_on: 00:01:00
    delay_off: 00:01:00

binary_sensors, sensors and templates are lists:

- binary_sensor:    
    - name: Close to Home
      state: '{{ states("proximity.home")|int < states("input_number.close_to_home_trigger")|int }}'

    - name: Night Mode
      unique_id: night_mode
      availability: '{{ not is_state("sensor.south_patio_illuminance_lux", "unavailable") }}'
      state: '{{ states("sensor.south_patio_illuminance_lux")|float(default=0) < states("input_number.outside_lux_trigger_point")|float(default=0) }}'
      delay_on: 00:02:00
      delay_off: 00:01:00

That’s what I had!

I’ll try it again…

Something is amiss…

template: !include_dir_merge_list templates/

Close to Home is working but the 2nd and subsequent entities are unavailable…

binary_sensor:    
  - name: Close to Home
    state: '{{ states("proximity.home")|int < states("input_number.close_to_home_trigger")|int }}'

  - name: Night Mode
    unique_id: night_mode
    availability: '{{ not is_state("sensor.south_patio_illuminance_lux", "unavailable") }}'
    state: '{{ states("sensor.south_patio_illuminance_lux")|float(default=0) < states("input_number.outside_lux_trigger_point")|float(default=0) }}'
    delay_on: 00:02:00
    delay_off: 00:01:00
    
  - name: Living Room Night Mode
    unique_id: living_room_night_mode
    availability: '{{ not is_state("sensor.south_patio_illuminance_lux", "unavailable") }}'
    state: '{{ states("sensor.south_patio_illuminance_lux")|float(default=0) < states("input_number.living_room_lux_trigger_point")|float(default=0) }}'
    delay_on: 00:01:00
    delay_off: 00:01:00

This one is fine…

select:
  - name: Select Destination
    unique_id: select_destination
    state: "{{ states('input_select.destination') }}"
    options: "{{ state_attr('input_select.destination','options') }}"
    select_option:
      service: input_select.select_option
      target:
        entity_id: input_select.destination
      data:
        option: "{{ option }}"
sensor:
  - name: "Direction of Travel"
    state: '{{ state_attr("proximity.home", "dir_of_travel") }}'
    
  - name: "Monthly Energy Cost: Car Charger"
    state: '{{ states("sensor.car_charging_step_1")|float(default=0) * states("input_number.bchydro_step_1_rate")|float(default=0) + states("sensor.car_charging_step_2")|float(default=0) * states("input_number.bchydro_step_2_rate")|float(default=0) }}'
    device_class: monetary
    unit_of_measurement: CAD

  - name: "Monthly Energy Cost: Coffee Maker"
    state: '{{ states("sensor.coffee_maker_step_1")|float(default=0) * states("input_number.bchydro_step_1_rate")|float(default=0) + states("sensor.coffee_maker_step_1")|float(default=0) * states("input_number.bchydro_step_2_rate")|float(default=0) }}'
    device_class: monetary
    unit_of_measurement: CAD

These new template triggers are preset & working…

template:
  - trigger:
    - platform: template
      value_template: "{{ (now() + timedelta(days=1)).day == 1 and now().hour == 23 and now().minute == 59 }}"
    sensor:
      - name: Last Month Car Charging Total Energy Cost
        state: "{{ states('sensor.node_50_electric_consumed_kwh') }}"

  - trigger:
    - platform: time_pattern
      seconds: "/5"
    sensor:
      - name: HASS Agent My PC Idle Time
        state: '{{ as_timestamp(utcnow()) - as_timestamp(states("sensor.lastactive")) }}'
        unit_of_measurement: "Seconds"
        
# Example configuration entry
  - trigger:
    - platform: time_pattern
      # This will update every night
      hours: 0
      minutes: 0
    sensor:
      # Keep track how many days have past since a date
      - name: Not smoking
        state: '{{ ( ( as_timestamp(now()) - as_timestamp(strptime("06.07.2018", "%d.%m.%Y")) ) / 86400 ) | round(default=0) }}'
        unit_of_measurement: "Days"

I think I found my problem…

Lack of " "…