Dynamically create items via Rule

  • Platform information:
    • Hardware: RPI5
    • OS: Debian
    • Java Runtime Environment: 17.0.14
    • openHAB version: 4.3.4

Hi All,

I am trying to create a set of new items dynamically via rule, I already saw this post, and thought it would be fairly simple, but can’t get it to work.

As I suspect Rik is going to ask: why?
What I want to do is produce a chart showing the sunrise over time in a curve using the Openhab charts.


As you can see, I have already done it for sunrise, but now I wanted to add all the other astro events to the same chart.

To get Openhab to do all the DB persistence and charting, I need to create an item for each event - I know I can manually create 20 events, and be done with it, but I thought it would be nice to make this fully automatic.

Here is my code:

function getEvents(sunEvent, sItem, sStart){
  var sunActions = actions.Things.getActions("astro","astro:sun:mylocation");
  if(null === sunActions) {
    console.log("actions: sunActions not found, check thing ID");
  } else {
    var oItem = items.getItem(sItem);
    if (oItem == null) {
      console.log("Creating new item:" + sItem);
      //var StringItem temporaryItem = (new StringItem(UUID.randomUUID().toString()));
      //temporaryItem.label = sItem;
    }
    
    // First, purge all existing persisted entries
    items.getItem(sItem).persistence.removeAllStatesBetween(time.ZonedDateTime.now().minusYears(1) ,time.ZonedDateTime.now().plusYears(1), 'jdbc');
        
    // Parse through every day, work out the start time of sunrise in decimals and persist it to the DB
    for (var i = -360; i <= 360; i++) {
      var today = time.ZonedDateTime.now().plusDays(i);  
      var sunEventTime = sunActions.getEventTime(sunEvent,today,sStart);
      var eventTime = (sunEventTime);
      var sTime = eventTime.toString();
      //2025-06-08T05:42+02:00
      var iHours = parseFloat(sTime.slice(11, 13));
      var iMins = parseFloat(sTime.slice(14, 16)/60)
      var nNewTime = (iHours+iMins).toFixed(2);
      
      console.log("AstroActions: "+sunEvent+" will happen at ", nNewTime);
      
      items.getItem(sItem).persistence.persist(today, nNewTime, 'jdbc');
    }
  }
}

getEvents("SUN_RISE","AstroSunriseStart", "START");

The 2 lines commented out just don’t work, they give this error:
image

Also, I suspect I need to create a numeric item, would this be?:
var NumericItem temporaryItem = (new NumericItem(UUID.randomUUID().toString()));

Any tips?

Thanks in advance
Will

I solved it myself, here is my code if anyone is interested:



function getEvents(sunEvent, sItem, sStart){
  var sunActions = actions.Things.getActions("astro","astro:sun:mylocation");
  if(null === sunActions) {
    console.log("actions: sunActions not found, check thing ID");
  } else {
    if (!items.existsItem(sItem)) {
      console.log("Creating new item:" + sItem);
      items.addItem({
        type: 'Number',
        name: sItem,
        label: sItem,
        groups: ['Astro'],
        category: '',
        tags: ['']
      })
    }
    
    // First, purge all existing persisted entries
    //items.getItem(sItem).persistence.removeAllStatesBetween(time.ZonedDateTime.now().minusYears(1) ,time.ZonedDateTime.now().plusYears(1), 'jdbc');
        
    // Parse through every day, work out the start time of sunrise in decimals and persist it to the DB
    for (var i = -360; i <= 360; i++) {
      var today = time.ZonedDateTime.now().plusDays(i);  
      var sunEventTime = sunActions.getEventTime(sunEvent,today,sStart);
      var eventTime = (sunEventTime);
      var sTime = eventTime.toString();
      //2025-06-08T05:42+02:00
      var iHours = parseFloat(sTime.slice(11, 13));
      var iMins = parseFloat(sTime.slice(14, 16)/60);
      var nNewTime = (iHours+iMins).toFixed(2);
      
      //console.log("AstroActions: "+sunEvent+" will happen at ", nNewTime);
      
      items.getItem(sItem).persistence.persist(today, nNewTime, 'jdbc');
    }
  }
}

//getEvents("SUN_RISE","AstroSunriseStart", "START");
//getEvents("SUN_SET","AstroSunsetStart", "START");
//getEvents("ASTRO_DAWN","AstroDawnStart", "START");
//getEvents("NAUTIC_DAWN","AstroNauticDawnStart", "START");
//getEvents("CIVIL_DAWN","AstroCivilDawnStart", "START");
//getEvents("ASTRO_DUSK","AstroDuskStart", "START");
//getEvents("NAUTIC_DUSK","AstroNauticDuskStart", "START");
//getEvents("CIVIL_DUSK","AstroCivilDuskStart", "START");
//getEvents("DAYLIGHT","AstroDaylightStart", "START");
//getEvents("NOON","AstroNoonStart", "START");
//getEvents("NIGHT","AstroNightStart", "START");
//getEvents("MORNING_NIGHT","AstroMorningNightStart", "START");
getEvents("EVENING_NIGHT","AstroEveningNightStart", "START");

And this is the result:

5 Likes

I never thought about creating items dynamically, this is really usefult, i use Sonos and my Sonos items needs to follow all the same naming schema to be used by rules, by automating items creation i can just create the main Sonos group, use metadata to define the thing UID and then create a script to fill up the Items.

Thanks for the idea!

1 Like

If you use “add equipment to model” you can create them all in one go.

But dynamically creating them is a good approach too. There are some gotchas to watch out for though and the created Items are not always permanent and will go away when you unload the role that created them.

Hmm… just to be clear do you mean Rule or Role? If Role, what role do you mean? my user account?

Rule is what I meant. Myopia and auto correct are the bane of my existence.