New rule engine startup - rule initialisation

Hello,

does someone experienced similar issue during openhab2 startup (build #660) when new rule system is not initializing rules because ot errors below? Rules are using zwave devices which are probably not yet initialized so maybe this may be the cause of this issue.


13:35:36.299 [INFO ] [smarthome.event.RuleStatusInfoEvent ] - rule_2 updated: NOT_INITIALIZED
13:35:36.371 [INFO ] [smarthome.event.RuleStatusInfoEvent ] - rule_2 updated: NOT_INITIALIZED (CONFIGURATION_ERROR): Validation of rule rule_2 has failed! Condition Type "ItemStateCondition" does not exist!
13:35:36.392 [INFO ] [smarthome.event.RuleStatusInfoEvent ] - rule_1 updated: NOT_INITIALIZED
13:35:36.432 [INFO ] [smarthome.event.RuleStatusInfoEvent ] - rule_1 updated: NOT_INITIALIZED (CONFIGURATION_ERROR): Validation of rule rule_1 has failed! Condition Type "ItemPostCommandAction" does not exist!
13:35:36.458 [INFO ] [smarthome.event.RuleStatusInfoEvent ] - rule_4 updated: NOT_INITIALIZED
13:35:36.492 [INFO ] [smarthome.event.RuleStatusInfoEvent ] - rule_4 updated: NOT_INITIALIZED (CONFIGURATION_ERROR): Validation of rule rule_4 has failed! Condition Type "ItemStateCondition" does not exist!
13:35:36.499 [INFO ] [smarthome.event.RuleStatusInfoEvent ] - rule_3 updated: NOT_INITIALIZED
13:35:36.511 [INFO ] [smarthome.event.RuleStatusInfoEvent ] - rule_3 updated: NOT_INITIALIZED (CONFIGURATION_ERROR): Validation of rule rule_3 has failed! Condition Type "ItemStateCondition" does not exist!

Thanks

EDIT: After disabling and enabling rule in paper ui they work correctly (and report as “idle”)

2 Likes

Hey there,
i have the same problem at build #662.
Somebody may has a solution or knows a workaround?

Greetings

Just updated to build #663.
Problem still exists.

Did you already report it at Issues · eclipse-archived/smarthome · GitHub or why did you expect it to be solved?

no, sorry, im quite new to OH and just wanted to tell everything that may helps.
I report the problem at github.

Ok, sorry, didn’t mean to be rude - note that the new rule engine is still under development, so it can be indeed quite buggy.
Many thanks for reporting any findings in the issue tracker!

I see this was reported and then closed as fixed: https://github.com/eclipse/smarthome/issues/2694

Did that fix make it into the stable release of OH2?, because I still experience this issue on OH2 (2.0.0-1)

ie Rules have a state of NOT_INITIALIZED after a restart.

The log has:

14:10:05.142 [INFO ] [smarthome.event.RuleStatusInfoEvent ] - rule_2 updated: NOT_INITIALIZED
14:10:05.222 [INFO ] [smarthome.event.RuleStatusInfoEvent ] - rule_2 updated: NOT_INITIALIZED (CONFIGURATION_ERROR): Validation of rule rule_2 has failed! Action Type "core.ItemCommandAction" does not exist!
14:10:05.241 [INFO ] [smarthome.event.RuleStatusInfoEvent ] - rule_1 updated: NOT_INITIALIZED
14:10:05.242 [INFO ] [smarthome.event.RuleStatusInfoEvent ] - rule_1 updated: NOT_INITIALIZED (CONFIGURATION_ERROR): Validation of rule rule_1 has failed! Action Type "core.ItemCommandAction" does not exist!

Im not using the rule engine anymore, because i switched to textual configuration, but may @Kai could tell us about this.

I also have seem similar effects, but not necessarily reproducible ones.
Have a try with a current snapshot, the code of the rule engine is still evolving quickly, so there is some progress.

it seem i have same problem as them
my log is

2017-04-02 20:51:20.413 [RuleStatusInfoEvent       ] - rule_5 updated: UNINITIALIZED (CONFIGURATION_ERROR): Validation of rule rule_5 has failed! Action Type "core.ItemCommandAction" does not exist!

can anyone fix it all rule are like that after startup

I have similar issues. Although my logs don’t show me anything about rules except this:

[ERROR] [xt.xbase.jvmmodel.JvmModelAssociator] - Error calling inferrer
java.lang.IllegalStateException: ScriptServiceUtil not initialized yet!
	at org.eclipse.smarthome.model.script.ScriptServiceUtil.getInstance(ScriptServiceUtil.java:88)
	at org.eclipse.smarthome.model.script.ScriptServiceUtil.getItemRegistry(ScriptServiceUtil.java:94)
	at org.eclipse.smarthome.model.script.internal.engine.ServiceTrackerItemRegistryProvider.get(ServiceTrackerItemRegistryProvider.java:29)
	at org.eclipse.smarthome.model.script.internal.engine.ServiceTrackerItemRegistryProvider.get(ServiceTrackerItemRegistryProvider.java:1)
	at org.eclipse.smarthome.model.rule.jvmmodel.RulesJvmModelInferrer.lambda$0(RulesJvmModelInferrer.java:175)
	at org.eclipse.xtext.xbase.jvmmodel.JvmModelAssociator$1.run(JvmModelAssociator.java:397)[146:org.eclipse.xtext.xbase:2.9.2.v20160428-1452]
	at org.eclipse.xtext.xbase.jvmmodel.JvmModelAssociator.installDerivedState(JvmModelAssociator.java:407)[146:org.eclipse.xtext.xbase:2.9.2.v20160428-1452]
	at org.eclipse.xtext.resource.DerivedStateAwareResource.installDerivedState(DerivedStateAwareResource.java:242)[142:org.eclipse.xtext:2.9.2]
	at org.eclipse.xtext.xbase.resource.BatchLinkableResource.getContents(BatchLinkableResource.java:148)[146:org.eclipse.xtext.xbase:2.9.2.v20160428-1452]
	at org.eclipse.smarthome.model.core.internal.ModelRepositoryImpl.validateModel(ModelRepositoryImpl.java:252)[123:org.eclipse.smarthome.model.core:0.9.0.201704291826]
	at org.eclipse.smarthome.model.core.internal.ModelRepositoryImpl.addOrRefreshModel(ModelRepositoryImpl.java:90)[123:org.eclipse.smarthome.model.core:0.9.0.201704291826]
	at org.eclipse.smarthome.model.core.internal.folder.FolderObserver.checkFile(FolderObserver.java:244)[123:org.eclipse.smarthome.model.core:0.9.0.201704291826]
	at org.eclipse.smarthome.model.core.internal.folder.FolderObserver.notifyUpdateToModelRepo(FolderObserver.java:170)[123:org.eclipse.smarthome.model.core:0.9.0.201704291826]
	at org.eclipse.smarthome.model.core.internal.folder.FolderObserver.updated(FolderObserver.java:148)[123:org.eclipse.smarthome.model.core:0.9.0.201704291826]
	at org.apache.felix.cm.impl.helper.ManagedServiceTracker.updated(ManagedServiceTracker.java:189)[3:org.apache.felix.configadmin:1.8.12]
	at org.apache.felix.cm.impl.helper.ManagedServiceTracker.updateService(ManagedServiceTracker.java:152)[3:org.apache.felix.configadmin:1.8.12]
	at org.apache.felix.cm.impl.helper.ManagedServiceTracker.provideConfiguration(ManagedServiceTracker.java:85)[3:org.apache.felix.configadmin:1.8.12]
	at org.apache.felix.cm.impl.ConfigurationManager$ManagedServiceUpdate.provide(ConfigurationManager.java:1461)[3:org.apache.felix.configadmin:1.8.12]
	at org.apache.felix.cm.impl.ConfigurationManager$ManagedServiceUpdate.run(ConfigurationManager.java:1417)[3:org.apache.felix.configadmin:1.8.12]
	at org.apache.felix.cm.impl.UpdateThread.run0(UpdateThread.java:141)[3:org.apache.felix.configadmin:1.8.12]
	at org.apache.felix.cm.impl.UpdateThread.run(UpdateThread.java:109)[3:org.apache.felix.configadmin:1.8.12]
	at java.lang.Thread.run(Thread.java:748)[:1.8.0_131]

I found that the API has the effect of initialising the rules, so added to my crontab to do this following my daily reboot:

0 5 * * * /sbin/shutdown -r +5
@reboot sleep 300; curl -X PUT --header "Content-Type: application/json" --header "Accept: application/json" -d "{}" "http://192.168.1.80:8080/rest/rules/rule_3/config"

You can get the rule name (rule_3 above) from the PaperUI if you set them up there.

1 Like

Got this problem too with openhab2 build #1020. My “fix” is a php script based on @Kev_Marlow suggestion:

<?php

function curlPost($url) {
  // Set a one-minute timeout for this script
  set_time_limit(60);

  $options = array(
    CURLOPT_RETURNTRANSFER => TRUE, // return web page
    CURLOPT_HEADER => FALSE, // don't return headers
    CURLOPT_POST => TRUE,
    CURLOPT_HTTPHEADER => array("Accept: application/json"),
  );

  $session = curl_init($url);
  curl_setopt_array($session, $options);

  // Tell curl that this is the body of the POST
  curl_setopt($session, CURLOPT_POSTFIELDS, $data);

  // $output contains the output string
  $output = curl_exec($session);
}

function curlPut($url, $data) {
  // Set a one-minute timeout for this script
  set_time_limit(60);

  $options = array(
    CURLOPT_RETURNTRANSFER => TRUE, // return web page
    CURLOPT_HEADER => FALSE, // don't return headers
    CURLOPT_CUSTOMREQUEST => "PUT",
    CURLOPT_HTTPHEADER => array("Content-Type: application/json", "Accept: application/json"),
  );

  $session = curl_init($url);
  curl_setopt_array($session, $options);

  // Tell curl that this is the body of the POST
  curl_setopt($session, CURLOPT_POSTFIELDS, $data);

  // $output contains the output string
  $output = curl_exec($session);
}

function curlGet($url) {
  // Set a one-minute timeout for this script
  set_time_limit(60);

  $options = array(
    CURLOPT_RETURNTRANSFER => TRUE, // return web page
    CURLOPT_HEADER => FALSE, // don't return headers
    CURLOPT_HTTPGET => TRUE,
    CURLOPT_HTTPHEADER => array("Accept: application/json"),
  );

  $session = curl_init($url);
  curl_setopt_array($session, $options);

  // $output contains the output string
  $output = curl_exec($session);
  return $output;
}

$output = curlGet("http://openhab:8080/rest/rules");
if (preg_match_all('/"uid"\:\"(.*?)\"/', $output, $matches)) {
  foreach ($matches[1] as $rule) {
    curlPut("http://openhab:8080/rest/rules/" . $rule . "/config", "{}");
  }
}

This can be also be done by writing old style rule which send HTTP put message as you suggested for each new JSON based rule configured. You may have to add error handling in this rule. You will have to enable jsonpath and javascript transformations in conf/services/addons.cfg file.

rule "InitializeAllRules"
when
System started
then
// Get all JSON based rules
var String jsonRules = sendHttpGetRequest(“http://127.0.0.1:8080/rest/rules”)
var String jsonuids = transform(“JSONPATH”, “$…uid”, jsonRules)
var String uidsAsString = jsonuids.substring(1, jsonuids.length - 1)

// Split rules uids
var uidsArray = uidsAsString.split(",")

// Update each rule
for (var i = 0; i < uidsArray.length; i++) {
  // Prepare API URL for config update
  var ruleConfigUrl = "http://127.0.0.1:8080/rest/rules/" 
    + uidsArray.get(i).substring(1, uidsArray.get(i).length - 1) + "/config"

  // Update config - This will initialize rule after starup
  sendHttpPutRequest(ruleConfigUrl, "application/json", "{}")
}

end

Hi @satish-nikam Satish,

Thanks for sharing your rule. I think an extra period has crept into the above script in line:

var String jsonuids = transform("JSONPATH", "$...uid", jsonRules)

The following worked for me:

rule "InitializeExperimentalRules"
  when
    System started
then
  // Get all JSON based rules
  var String jsonRules = sendHttpGetRequest("http://127.0.0.1:8080/rest/rules")
  var String jsonuids = transform("JSONPATH", "$..uid", jsonRules)
  var String uidsAsString = jsonuids.substring(1, jsonuids.length - 1)

  // Split rules uids
  var uidsArray = uidsAsString.split(",")

  // Update each rule
  for (var i = 0; i < uidsArray.length; i++) {
  // Prepare API URL for config update
  logInfo("InitializeExperimentalRules", uidsArray.get(i))
  var ruleConfigUrl = "http://127.0.0.1:8080/rest/rules/" + uidsArray.get(i).substring(1, uidsArray.get(i).length - 1) + "/config"
  

  // Update config - This will initialize rule after starup
  sendHttpPutRequest(ruleConfigUrl, "application/json", "{}")
}
end

Regards, Andy

2 Likes

That did not work for me.

I think it might be that the rules are initialising too soon.
I see this in the rest/rules:

enabled true
status
status “UNINITIALIZED”
statusDetail “CONFIGURATION_ERROR”
description “Validation of rule rule_12 has failed! Condition Type "timer.DayOfWeekCondition" does not exist!”

yet disabling and enabling the rule works

1 Like

Thank you andy, your workaround worked for me!

Hey guys is this workaround still working. i cant get it to work anymore, i am using openHAB 2.3.0 Build #1272. I also tried the script but it generates errors.

1 Like

Hi @satish-nikam and @AndyMB,
I don’t know if there was a change in the rest api in 2.3.0, but I managed to create a workaround, based on your solutions. There are better ways to cut the UID out of the json string than iterating over the chunks of the split until “uid” is found in the string, but it works for me for now.

rule "InitializeExperimentalRules"
  when
    System started
then
  // Get all JSON based rules
  var String jsonRules = sendHttpGetRequest("http://127.0.0.1:8080/rest/rules")
  var String jsonuids = transform("JSONPATH", "$..uid", jsonRules)
  var String uidsAsString = jsonuids.substring(1, jsonuids.length - 1)
  // Split rules uids
  var uidsArray = uidsAsString.split(",")
  // Update each rule
  for (var i = 0; i < uidsArray.length; i++) {
  // Prepare API URL for config update
  //Check if the current chunk of the split string contains "uid" (this is dirty, but works)
  if(uidsArray.get(i).contains("uid")){
    
    //get the substring which represents the uid string e.g. Rule_1
    var String uid = uidsArray.get(i).substring(7, uidsArray.get(i).length - 1)
    //Build the URL for updating the Rule
    var String ruleConfigUrl = "http://127.0.0.1:8080/rest/rules/" + uid + "/config" 
    //Log the Rule update with the UID
    logInfo("INFO","Rule "+uid+" updated: "+ruleConfigUrl)
    //send the http put request to update the rule
    sendHttpPutRequest(ruleConfigUrl, "application/json", "{}")
  }
  
}
end
1 Like

You missed a couple of brackets and the closing END, besides that your script works perfectly.
Here the corrected version

rule "InitializeExperimentalRules"
  when
    System started
then
  // Get all JSON based rules
  var String jsonRules = sendHttpGetRequest("http://127.0.0.1:8080/rest/rules")
  var String jsonuids = transform("JSONPATH", "$..uid", jsonRules)
  var String uidsAsString = jsonuids.substring(1, jsonuids.length - 1)
  // Split rules uids
  var uidsArray = uidsAsString.split(",")
  // Update each rule
  for (var i = 0; i < uidsArray.length; i++) {
  // Prepare API URL for config update
  //Check if the current chunk of the split string contains "uid" (this is dirty, but works)
  if(uidsArray.get(i).contains("uid")){
    
    //get the substring which represents the uid string e.g. Rule_1
    var String uid = uidsArray.get(i).substring(7, uidsArray.get(i).length - 1)
    //Build the URL for updating the Rule
    var String ruleConfigUrl = "http://127.0.0.1:8080/rest/rules/" + uid + "/config" 
    //Log the Rule update with the UID
    logInfo("INFO","Rule "+uid+" updated: "+ruleConfigUrl)
    //send the http put request to update the rule
    sendHttpPutRequest(ruleConfigUrl, "application/json", "{}")
  }
  }
  end