How could I have done this better?

As part of my learning the ropes, I have been setting up various notifications for the changes in status of my solar installation. For this part, I wanted to send a notification each time we generate another MWh of energy. So, I did this by creating a binary sensor based on the value from the solaredge sensor as

template:
  - binary_sensor:
       - unique_id: solar_megawatt_boundary
        name: "MWh boundary crossed for solar generation"
        state: "{{ states('sensor.solaredge_lifetime_energy')|float /1000000 - int(states('sensor.solaredge_lifetime_energy') |float /1000000) == 0}}"

Which I think works (I couldn’t find a modulus operator - is there one? ). It simply sets true on each modulus of 1MWh

I then created a simple automation as

- id: '1663491291155'
  alias: Announce each MWh of solar
  description: Announce each time we generate another MWh of power
  trigger:
  - platform: state
    entity_id:
    - sensor.mwh_boundary_crossed_for_solar_generation
    to: 'on'
  condition: []
  action:
  - service: notify.telegram_family
    data:
      title: Announcement
      message: We now now generated {{ int(     states('sensor.solaredge_lifetime_energy')|float
        /1000000) }} MWh of energy since installation!
  mode: single

I’m sure that there must be a cleaner way of doing this. Also, I am aware that this may well fail if HA misses the crossing, which is probably likely. So, a threshold crossing would be far better but I can’t see how to do that.

TIA for any advice.

Yes there is. Also make sure you supply a default for your float filters.

template:
  - binary_sensor:
       - unique_id: solar_megawatt_boundary
        name: "MWh boundary crossed for solar generation"
        state: "{{ states('sensor.solaredge_lifetime_energy')|float(1) % 1000000 ==  0 }}"
        availability: "{{ states('sensor.solaredge_lifetime_energy')|is_number }}"

The availability template will make the binary sensor state unknown if your energy sensor is not able to be converted to a number (if it is unknown, or unavailable).

Your trigger is not quite correct. The entity_id should be:

  trigger:
  - platform: state
    entity_id:
    - binary_sensor.mwh_boundary_crossed_for_solar_generation
    from: 'off'
    to: 'on'

Adding the from will prevent trigging if the sensor goes on → unknown → on.

That’s fantastic, thank you. I was closer than I thought, which is encouraging.

With the sensor, I assume that will also trigger if it goes from 0.9 → 1.1? That is the actual transition isn’t recorded as the actual solaredge sensor only updates every 15 minutes or so, I believe.

Hmm, no. The energy sensor state has to be exactly a multiple of 1MWh.

Ah, I suspect that that might be a problem, then. I imagine it’s unlikely that the integration will pick up the precise value as it changes.

Maybe I should be looking for a change in the integer value of the shifted reading?

/me thinking out loud.

The trouble with using the integer is that n%1 is always true when n is an integer.

How much would it overshoot by?

You could do something like this:

state: "{{ states('sensor.solaredge_lifetime_energy')|float(1) % 1000000 <=  1000 }}"

EDIT: no, don’t do this.

I meant eschewing the modulus and simply extracting the integer value of the shifted sensor input and then seeing if it changes. I don’t need this to be precise, just that when it changes from below the modulus to above (once each MWh) that the automation is triggered.

(NB sorry if I’m using the wrong terminology there)

That is…

      - unique_id : solar_generation_megawatthours
        name: "Number of Megawatt Hours Generated"
        state:  "{{ int(states('sensor.solaredge_lifetime_energy') |float /1000000) }}"
        availability: "{{ states('sensor.solaredge_lifetime_energy')| is_number }}"

and

- id: '1663491291155'
  alias: Announce each MWh of solar
  description: Announce each time we generate another MWh of energy
  trigger:
  - platform: state
    entity_id:
    - sensor.solar_generation_megawatthours
  condition: []
  action:
  - service: notify.telegram_family
    data:
      title: Announcement
      message: We have now generated {{ int(states('sensor.solaredge_lifetime_energy')|float
        /1000000) }} MWh of energy since installation!
  mode: single