Scene Control Suite - Scene Activation

Hi Justin
Your work is brilliant! It saves me many hours of work, if I had ever done it at all. More likely, I would have gotten stuck in a flood of rules and then given up in frustration…

Unfortunately, I made a mistake somewhere, but I just can’t find it. When I try to manually trigger the rule “Scene Control Suite - Scene Activation Abendstimmung”, I get the following error:

2022-01-06 11:36:14.236 [ERROR] [internal.handler.ScriptActionHandler] - Script execution of rule with UID '24d3069bce' failed: <eval>:38:38 Expected ident but found {

run_controller('{{sceneController}}',{{undoSettings}})

                                      ^ in <eval> at line number 38 at column number 38`Preformatted text`

The rule (I changed nothing):

configuration: {}
triggers:
  - id: "4"
    configuration:
      itemName: Scene_Control_Suite_Abendstimmung
    type: core.ItemCommandTrigger
conditions:
  - inputs: {}
    id: "3"
    configuration:
      itemName: Scene_Control_Suite_Abendstimmung
      state: ON
      operator: =
    type: core.ItemStateCondition
actions:
  - inputs: {}
    id: "2"
    configuration:
      type: application/javascript
      script: >-
        /*

        This Script activates the items in a Scene Controllers ActiveItems metadata.

        */

        //Nashorn and JSscripting compatibility

        if(typeof(require) === "function") Object.assign(this, require('@runtime'));

        //Set Logger

        var logger = Java.type('org.slf4j.LoggerFactory').getLogger('org.openhab.rule.runController');


        //Access MetadataRegistry

        var FrameworkUtil = Java.type('org.osgi.framework.FrameworkUtil');

        this.ScriptHandler = Java.type("org.openhab.core.automation.module.script.rulesupport.shared.ScriptedHandler");

        var _bundle = FrameworkUtil.getBundle(ScriptHandler.class);

        var bundle_context = _bundle.getBundleContext();

        var MetadataRegistry_Ref = bundle_context.getServiceReference('org.openhab.core.items.MetadataRegistry');

        var MetadataRegistry = bundle_context.getService(MetadataRegistry_Ref);

        var MetadataKey = Java.type('org.openhab.core.items.MetadataKey');


        //Function To Read Scene Metadata And Activate Items

        run_controller = function (controllerID, undoSettings) {
        	undoSettings = undoSettings || false;
        	var metaList = MetadataRegistry.get(new MetadataKey('ActiveItems',controllerID));
        	if (metaList && undoSettings) {
        	var configList = metaList['configuration'];
        	for (var id in configList) {
        		events.sendCommand(id,(configList[id] == 'ON') ? 'OFF' : ((configList[id]) == 'OFF' ? 'ON' : configList[id]));
        	};
        	} else if (metaList) {
        	var configList = metaList['configuration'];
        	for (var id in configList) {
        		events.sendCommand(id,configList[id]);
        	};
        	} else {
        	logger.info(['No items currently controlled by ',controllerID].join(''));
        	};
        };


        //Activate

        run_controller('{{sceneController}}',{{undoSettings}})
    type: script.ScriptAction

The metadata looks like this:

value: ADD
config:
  Baum_Tief_Helligkeit: "26"
  Baum_Tief_Farbtemperatur: "100"
  Baum_Zentrum_Farbtemperatur: "68"

As I understand it, I don’t use the “undo parameter” at all. But it seems that I do?

Before I set up the whole thing again, I wanted to try my luck first here. I hope that it is only a small thing that you know immediately.

Thanks again for your work!

Hi Mark, welcome to the forums.

The double brace “{{” is not valid javascript. These are placeholders used by the rule templates, and should have been replaced by your selected values when you created a new instance of this rule template. Are you using the new full release of OH3.2? There was a breaking change in 3.2 that uses a different placeholder syntax than previous versions, so this rule won’t work as a rule template for most of the snapshots or milestones leading up to the full release of 3.2.

Fortunately, the fix is fairly easy for now. You can do the replace manually. {{sceneController}} just needs to be replaced by the name of the item holding your metadata, and {{undoSettings}} can just be replaced by false or removed altogether. So the line would look something like this:

run_controller('SceneMorning',false)

or just

run_controller('SceneMorning')

I do also see a couple other small things in the rule and metadata that may present some difficulties. So, we should try and get those cleared up too.

You have the same item name for the rule trigger and the rule condition. I assume that this item is the one that has the metadata. In that case it is correct to have this item name in the conditions section of the rule. That part is what allows you to disable this scene completely in case there’s some reason you don’t want the scene to even be able to be activated. In the trigger section some separate item or event is expected. This is whatever you are going to do to tell the system you want this particular scene. Maybe that’s a a button push, or toggling a switch on the UI or even just an astro event.

Again, this is very easy to fix at this point since you already have the rule in the UI you can just open up the rule page, push the red button next to the current trigger to delete it and then press the green “Add trigger” button to set up a new sensible trigger.

This shouldn’t actually impact the system at all, but the scene system doesn’t use the value of the metadata at all, just the config so having value: ADD isn’t doing anything for the system.

1 Like

Yes, now it works!

Good I asked you - that I have to adjust the rule was not clear to me. Unfortunately I can’t code Java myself just read it approximately. So I didn’t recognized the placeholder as such.

The “ADD” in the metadata was a test, which I forgot to delete…

That the rule trigger and the rule condition should not be the same item makes sense. But probably without your help it would have taken me a lot of time to figure it out.

I am a newcomer to Openhab, German speaking and it’s been more than 30 years since I worked as a programmer. Accordingly, I am quite (over-)challenged at the moment. And only through the support of people like you, it makes sense for me to get into all of this!!!

Thanks! :pray:

Btw - my Raspberry Pi 3 is running Openhab 3.2.

Hello Justin

I’m not sure if this post belongs here, if not report it to me and I’ll delete it…but maybe it’s helpful in some way.

I have among other things Ikea-Tradfri bulps with color spectrum. For this I had to customize the widget and Scene Control Suite - Scene Activation rule.

Screenshots:

Without customization

With customization

The Tradfri bulp needs only one field for all color and brightness parameters. The separator inside the field is the “,” which unfortunately is also used in the code to manage the metadata.

My solution is very “primitive”, because of my minimal Java knowledge. But I am glad that it works at all:

When writing the metadata I replace the “,” with a “ç”. And when outputting the metadata I change the “ç” back to a “,”.
I chose the “ç” because I am pretty sure that this character is not used by Java.

My changes:

Scene Control Suite - Scene Activation Rule:

//    	events.sendCommand(id,(configList[id] == 'ON') ? 'OFF' : ((configList[id]) == 'OFF' ? 'ON' : configList[id]));
		events.sendCommand(id,(configList[id] == 'ON') ? 'OFF' : ((configList[id]) == 'OFF' ? 'ON' : configList[id].replaceAll("ç", ",")));

Scene Control Suite - Scene Modification Rule:

//Take metadata write/delete action based on modification
  if (modification == 'ADD' || modification == 'REFRESH') {
    //Format metadata to write
    var targetState = items[targetName].toString();
    
    //New Line:
    targetState = targetState.replaceAll(",", "ç");
    
    var targetData={};
    targetData[targetName]=targetState;

widgets:scene_controller:
Line 73:

  badge: =loop.activeItem.split(':')[1].slice(1,-1).replaceAll("ç", ",")

1 Like

Thanks Mark, that’s a great point. I don’t use any color items in my scenes so I had missed this issue with commas. You solution is pretty much right on track with what I would have done. I’ll see if I got a chance in the near future to update all the pieces.

1 Like

Turns out the fix can be entirely contained in the widget code. I’ve added the update to the widget code. If you update the widget you’ll need to revert the rules back to their original forms (and update the metadata).

1 Like

I knew you would find a more efficient solution :+1:
Perfect, thank you very much!

hi there

thank you for your idea and your widget. It hink I don´t know how to get it to work, as my widget stays empty.


Widget_2

I’ve created one rule for activation, and one for modification.

configuration:
  undoSettings: false
  triggerState: ON
  sceneController: Scene_Controller
  triggerItem: KNX_Buero_DL_schalten
triggers:
  - id: "4"
    configuration:
      itemName: KNX_Buero_DL_schalten
      command: ON
    type: core.ItemCommandTrigger
conditions:
  - inputs: {}
    id: "3"
    configuration:
      itemName: Scene_Controller
      state: "true"
      operator: =
    type: core.ItemStateCondition
actions:
  - inputs: {}
    id: "2"
    configuration:
      type: application/javascript
      script: >-
        /*

        This Script activates the items in a Scene Controllers ActiveItems metadata.

        */

        //Nashorn and JSscripting compatibility

        if(typeof(require) === "function") Object.assign(this, require('@runtime'));

        //Set Logger

        var logger = Java.type('org.slf4j.LoggerFactory').getLogger('org.openhab.rule.runController');


        //Access MetadataRegistry

        var FrameworkUtil = Java.type('org.osgi.framework.FrameworkUtil');

        this.ScriptHandler = Java.type("org.openhab.core.automation.module.script.rulesupport.shared.ScriptedHandler");

        var _bundle = FrameworkUtil.getBundle(ScriptHandler.class);

        var bundle_context = _bundle.getBundleContext();

        var MetadataRegistry_Ref = bundle_context.getServiceReference('org.openhab.core.items.MetadataRegistry');

        var MetadataRegistry = bundle_context.getService(MetadataRegistry_Ref);

        var MetadataKey = Java.type('org.openhab.core.items.MetadataKey');


        //Function To Read Scene Metadata And Activate Items

        run_controller = function (controllerID, undoSettings) {
        	undoSettings = undoSettings || false;
        	var metaList = MetadataRegistry.get(new MetadataKey('ActiveItems',controllerID));
        	if (metaList && undoSettings) {
        	var configList = metaList['configuration'];
        	for (var id in configList) {
        		events.sendCommand(id,(configList[id] == 'ON') ? 'OFF' : ((configList[id]) == 'OFF' ? 'ON' : configList[id]));
        	};
        	} else if (metaList) {
        	var configList = metaList['configuration'];
        	for (var id in configList) {
        		events.sendCommand(id,configList[id]);
        	};
        	} else {
        	logger.info(['No items currently controlled by ',controllerID].join(''));
        	};
        };


        //Activate

        run_controller('Scene_Controller',false)
    type: script.ScriptAction

The modification rule is emty.

BR

The widget only shows items that have been configured with the proper tag. Have you read through the setup section on the tutorial? If you have the proper items, they will show up in the widget whether the rules are properly configured or not.

How did you create the rules? The text you’ve posted is not correct, it still contains the configuration section of the rule template. These rules are posted here in the market-place as rules templates, which are not exactly the same as rules. You have to install the rules templates using the Add-onsAutomation section of the settings page of your OH instance. Then these rule templates get translated into correctly formatted rules if you create a new rule using the template.

If you did install using the market-place, what version of OH are you using?

Hi Justin

First of all, I must apologize for my late feedback.
I have now found the error and the controller items show up in the list.

I have also created the two rules.
Unfortunately, it still does not seem to work.
When I change something in the widget or press refresh, I see it in the log files as follows:

2022-04-18 22:26:28.880 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'Rule_SceneModify' changed from Scene_Guten_Morgen,KNX_Buero_DL_schalten,REFRESH to None

I have the two rules in the attachment.

If I now switch the Activation Item DL_Buero to ON, nothing happens.

Somewhere I seem to have a logical error

BR
Daniel
activation_rule.txt (2.5 KB)
modify_rule.txt (3.8 KB)

That should be correct. When you click on one of the actions in the widget, the widget sends a command to the Rule_SceneModify item that is a string with various information in it. When that item changes its state in response to the command, it triggers the modify rule. The modify rule reads the information it needs from the item state and performs the indicated modification. As a last step, the rule then resets the value of the rule item to None. The fact that you are seeing that line in the log means that the modify rule is running properly.

It looks like there are two issues with your activation rule in the condition section (the ‘But only if…’ part of the rule).

  1. Your configuration state says true instead of ON, but that’s because there was a bug in the way the rules templates were setting some values. I fixed that error a couple days ago, but if you still have the old version you downloaded before then you’re still subject to that error when you create a new activation rule. You can get the new version with the bug fix, by removing and re-adding the rule template.

  2. You have configured the condition item to be Rule_SceneModify when this is intended to be the name of the controller item (in the example you sent Scene_Guten_Morgen). The idea here is to take advantage of the fact that the scene controllers are switches and allow you to disable the scene. You want your Guten Morgen scene to run most mornings, I imagine, but what if you’re on vacation? Maybe it doesn’t make sense to have the scene run then. In that case you can use the widget to switch the scene controller to off (“disabled” in the widget). The activation rule is supposed to check the state of the scene controller itself before activating and if the scene controller has been set to OFF (deactivated) the then rule will not run.

One way or the other you want the rule to look like this in the end if you want to use this ability to disable the scene:


Only in your case the item is Scene_Guten_Morgen.

Thank you - now it works like a charm.

I really appreciate your help

BR
Daniel

1 Like

I guess this is was not update for OH4 since the last post was almost 18 months ago

I have not updated this for OH4. In OH you now have access to the built in scenes, so this seemed redundant, and, in fact, I no longer use it myself. I just use the native OH scenes.

Off the top of my head, however, I can’t think of any reason why it should have any conflicts with OH4.

1 Like

It doesn’t like the call to library for the controller function. I am working on converting to the built in scenes now.

I’m not sure what this actually refers to; this rule doesn’t use any external libraries. But, if you’re going to the built in scenes anyway, then I won’t worry about.

Just out of curiousity, how do handle enabling and disabling scenes?

I have one additional switch item for each scene. In the rule that calls the scene to run, that switch item is checked in the rule conditions. So if the switch is off, the scene will not be activated even if the other triggers for the rule do occur. (In fact, I have several such items as there are also generic times when whole batches of scenes are disabled such as when the family is on vacation.)

You can also, if you prefer, use rules to control whether other rules (including scenes) are enabled or disabled via the rule actions.

1 Like

Thanks

It might be worth adding the versioning string to the title so it doesn’t show up in MainUI for those running OH 4. “[3.3.0;3.4.9)” captures all OH 3 versions from 3.3.0 to the last 3.4 release but will hide these entries in MainUI for those running OH 4.

The warning there is you’ll get an error in the logs when a disabled rule (a Scene is just a rule after all) is called.