Need help with setting and calculating "time of day"

Having worked with OpenHAB since 2015 I have now decided to migrate to HA. Main reasons are Lovelace with all cards and add-ons, the extremely professional documentation and that OH3 will introduce some breaking changes that I cannot accept.

Enough said, I am still quite a noob, especially when it comes to writing automations that are time dependant. One major building block in my automation is a sensor that reports the time of day as a string. Here are the requirements:

From midnight to a fixed time (06:30) it is NIGHT
From 06:30 to 07:15 it is EARLY_MORNING
From 07:15 to Sunrise it is MORNING
From Sunrise to Sunset it is DAY
From Sunset to Dusk it is AFTERNOON
From Dusk to 23:30 it is EVENING
From 23:30 to midnight it is NIGHT

Here in Sweden, the sun might rise in the summer already before 06:30 so in that case the time of day goes directly from NIGHT to DAY or from EARLY MORNING to DAY

This is the way it is done in OpenHAB:

val logName = "timeofday"

	rule "Calculate time of day state"
	when
  	System started or
  		Time cron "0 1 0 * * ? *" or
		Time cron "0 30 6 * * ? *" or
  		Time cron "0 15 7 * * ? *" or
  		Channel 'astro:sun:ff35f917:rise#event' triggered START or
  		Channel 'astro:sun:ff35f917:set#event' triggered END or
  		Channel 'astro:sun:ff35f917:civilDusk#event' triggered END or
  		Time cron "0 30 23 * * ? *" 
	then
  		
  		val earlymorning_start = now.withTimeAtStartOfDay.plusDays(1).minusMinutes(1050)  // 06:30 Start of early morning
		logInfo(logName, "earlymorning_start" + earlymorning_start.toString)
		val morning_start = now.withTimeAtStartOfDay.plusDays(1).minusMinutes(1005) // 07:15 Start of morning
  		logInfo(logName, "morning_start" + morning_start.toString)
  		val night_start = now.withTimeAtStartOfDay.plusDays(1).minusMinutes(30) // 23:30 Start of night
  		logInfo(logName, "night_start" + night_start.toString)

		// Convert the Astro Items to Joda DateTime  
		val day_start = new DateTime(Solna_AstroSunData_Rise_StartTime.state.toString)
  		logInfo(logName, "day_start" + day_start)
  		val afternoon_start = new DateTime(Solna_AstroSunData_Set_EndTime.state.toString)
  		logInfo(logName, "afternoon_start" + afternoon_start)
 		 val evening_start = new DateTime(Solna_AstroSunData_CivilDawn_EndTime.state.toString)
  		logInfo(logName, "evening_start" + evening_start)
  		
  
  		var curr = "UNKNOWN"

  	switch now {
        case now.isBefore(earlymorning_start):							  		curr = "NIGHT"
		case now.isAfter(earlymorning_start) && now.isBefore(morning_start):	curr = "EARLYMORNING"
        case now.isAfter(morning_start) && now.isBefore(day_start):       		curr = "MORNING"
        case now.isAfter(day_start) && now.isBefore(afternoon_start):     		curr = "DAY"
        case now.isAfter(afternoon_start) && now.isBefore(evening_start): 		curr = "AFTERNOON"
        case now.isAfter(evening_start) && now.isBefore(night_start):     		curr = "EVENING"
        case now.isAfter(night_start):     								  		curr = "NIGHT"
 	 }

  	
   		logInfo(logName, "Current time of day is now " + curr)
    	Solna_TimeOfDay.sendCommand(curr)
		Solna_TimeOfDay.postUpdate(curr.toString)
  	

	end

I am just not skilled enough to translate this into Ninja? vocabulary. If someone could help me to at least get started I would be eternally grateful.
As you see all times are calculated starting from the end of the day and then counting backwards.

1 Like

I would create an input.select helper (you can find this in the UI with the automations), that’s a list of the time of day strings.

Then create an automation that has the time and sun as triggers.
In the action part, create a choose action that looks at the state of the time and sun and subsequently sets the value of the helper.

There will be some templating involved, so I’d look into that, but coming from OpenHab, i’m assuming that won’t be a problem for you.