Real Horizon — terrain-aware sunrise/sunset & a sun/moon card (prototype, feedback welcome)

If your house is in a valley, against a ridge, or up against any non-flat terrain, Home Assistant's sun.sun lies to you. It computes sunrise and sunset against a flat ocean horizon — so on a 20° terrain horizon your actual sunset can be up to two hours earlier than HA reports.

Real Horizon fetches the 360° terrain horizon for your HA latitude / longitude from https://re.jrc.ec.europa.eu/ (free, no API key, SRTM-derived, global) and computes the moment the sun actually clears the local horizon. Same for the moon. Comes with a Lovelace card that draws today's sun and moon arcs over the silhouette of your real horizon.

What you get

  • sensor.real_horizon_true_sunrise / _true_sunset — terrain-aware timestamps
  • binary_sensor.real_horizon_sun_above_local_horizon — useful for "only run automation while the sun is actually visible"
  • sensor.real_horizon_sun_clearance — current sun_altitude − horizon(sun_azimuth), in degrees
  • sensor.real_horizon_local_horizon_profile — the full 360° profile + moon position + horizon-aware moonrise/moonset (consumed by the card)

Install (HACS, as a custom repository)

  1. HACS → Integrations → ⋮ → Custom repositories → add https://github.com/kali/real-horizon (category: Integration).
  2. Install, restart, Settings → Devices & services → Add integration → Real Horizon.
  3. On any dashboard:
  type: custom:real-horizon-card
  entity: sensor.real_horizon_local_horizon_profile

Are you aware of the very mature sun2 integration and that it covers this functionality, among other improvements over the built-in sun integration?

Well, I did look for a solution before coding this. If sun2 can cope with a complex terrain horizon, I must have missed it.

1 Like

I use sun2 too, so I am not sure what sun.sun can do.

What I do know is that sun.sun has issues with elevation value.
The elevation in the user settings has a description that says it is the elevation over the ocean level and that is what sun.sun use.
However the sun algorithm behind sun.sun needs an elevation over ground level, so sun.sun calculated it wrong.

Sun2 does not rely on the elevation level in the user settings.

But I think none of the integrations have this feature and actually think only sun2 can fully utilize it, due to the issues described above with sun.sun.

I'm not sure if you mistyped, but sun2 definitely supports this. I followed the deep discussions into this at the time.

I know that you can set the observer elevation in Sun2 and it actually then makes the right calculations.
You can also set the observer elevation in sun.sun by setting the elevation value in the user settings.

What none of the integrations do is find the actual value for you automatically and this integration here seems to do that.

What i propose is not limited to user elevation. It pulls from pvgis a full horizon profile around your location. My place is deep in a valley. If you don't take into account the relief around my place, these days, sunrise is off by one hour, sunset by two hours. And it's not even that dramatic a landscape, this is not Yosemite, just a valley in hills. This is not the ~3min induced by refraction and solar disk size. It essentially make these times useless for automation. With my integration, i get at ~10min. No configuration, and a cute (I think) lovelace card.

If you're on flat terrain, sun will work fine. If there is a building or a tree somewhere, my understanding is, you can hack around it with sun2. But if the dominating feature determining your horizon is terrain, I think this integration can help.