The scene doesn’t really cover that part. The scenes are what to do, not when to do it. For the when to do it you need to set the rule triggers.
There are ways to be clever to have one rule without a bunch of conditionals.
Yes, scenes do not use JS Scripting so there is no multi-threaded problems like there is with multiple rules calling the same JS Scripting Script (i.e. a rule defined under Settings → Scripts).
What I don’t know is how these events come across. Are they Item updates? Event Channel triggers? Something else? Because of that lack I can’t really give you a concrete example to go off of.
But using scenes there are the following general options. In all these cases each scene (i.e. the commands to send to each Item in the scene) is defined in Settings → Scenes.
-
Create one Rule (Settings → Rules) per Scene. Here is where you define the “when button 1 is pressed once” which is the trigger if this rule. Without more details I cannot tell you what that trigger needs to be. The action is a simple “call rule” with the proper scene as the rule to call. This is the most straight forward, but it results in the largest number of rules with at least two per scene.
-
Instead of creating a separate rule to control when the scene triggers, manually add the triggers to the Scene from the code tab of the scene. To figure out the proper syntax, create a Rule (Settings → Rules), add an example trigger, and then copy the YAML for that trigger from the code tab. Paste/edit it in the code tab for the corresponding Scene. This approach avoids needing 2 rules per Scene, but it requires manually messing with the code of the Scenes. This is the approach I use.
-
Create one rule (Settings → Rules) which is triggered by all the button press events. Inside the rule, use what triggered it to create the UID of the Scene to call. But for this to work, when you create your Scenes, you need to create them with a UID that can be calculated from what ever triggered the rule. This is very similar to Design Pattern: Associated Items only we are calculating the UID of the Scene instead of the name of an Item.
Creating the scenes is easy and straight forward. But because I don’t know how these button press events come through I can only wave my hands at what the triggers would be. Because these are button presses I would assume they are Channel events and not Items. If that is case I’d need to know what event.event looks like to craft the rule trigger.
Based on your code though it looks like it’s an Item. If that’s the case, option 1 is pretty straight forward. The Rule trigger will be an Item Updated trigger for with Item SceneControllerState and state 1.3 (for example). The action will be a rule action to call the corresponding scene.
It would look like this only this is using my Item names instead of yours. The UI only lets you select existing Items and I don’t want to create a bunch of example Items for these screenshots. You’d select your SceneControllerState Item and put what ever you are using as the key in your dict.
Then add a simple rule action to call the corresponding scene.
The YAML for the final rule looks like this:
configuration: {}
triggers:
- id: "1"
configuration:
itemName: TimeOfDay
state: AFTERNOON
type: core.ItemStateUpdateTrigger
conditions: []
actions:
- id: "2"
configuration:
ruleUIDs:
- lights_afternoon
type: core.RunRuleAction
Repeat for each scene.
One advantage of this approach is it’s easy to add triggers from other sources (e.g. a presence simulation rule, Astro sunrise/sunset events, motion events, etc.). It’s also easy to add conditions (e.g. don’t allow the rule to run when you are not home or it’s between 22:00 and 06:00).
Option 2 will use the YAML I pasted in above. Copy the triggers section. Then navigate to the Scene. Open the code tab and replace the triggers: [] line with what you’ve copied.
Before:
items:
FrontPorchLight: ON
PatioLights_Switch: ON
FamilyRoomOutlet: ON
PeanutPlug4_Switch: ON
FrontRoomOutlet: ON
FamilyRoomLampShelves: ON
triggers: []
conditions: []
After:
items:
FrontPorchLight: ON
PatioLights_Switch: ON
FamilyRoomOutlet: ON
PeanutPlug4_Switch: ON
FrontRoomOutlet: ON
FamilyRoomLampShelves: ON
triggers:
- id: "1"
configuration:
itemName: TimeOfDay
state: AFTERNOON
type: core.ItemStateUpdateTrigger
conditions: []
Repeat for the rest of your scenes, only change the “state” part of the trigger to the state SceneControllerState should update to in order to cause that scene to run.
Obviously you can add additional triggers and add conditions like described above, but you’ll have to look up/experiment to get the right YAML for each.
For option 3, you’d careful set the UIDs of your Scenes to correspond with state that should trigger it. It looks like it follows the pattern “Number”.“Number”. so, for example, we’d use as the UID for the scene that corresponds to 1.3 might be something like “garage1_3”. If that’s the case your JS rule would trigger on any update to SceneControllerState and the code would be something like:
var sceneID = "garage"+event.itemState.replace('.', '_');
rules.runRule(sceneID, {}, true);
The logic gets much more complicated if you have more triggers though and if you have conditions you’ll want to put those on the Scene as described in option 2.
Some notes about your code as written:
Please use code fences for code and logs:
```
code goes here
```
The current approach can handle only one Item per scene. Your stated your goal is to handle multiple Items per scene. You can do that in your map using an array for each key instead of just a String. Then you need to loop through the array and command each Item. But you also need to add what to command the Item to, so the array needs to be an array of arrays.
var ItemDict = { '1.0': [ ['outlet1', 'ON'], ['outlet2, 'OFF']'], '1.1'...
...
targetItemTuples.forEach( i => items[i[0]].sendCommand(i[1]))
You should define variables using var, let, or const. However, unless you are between { } only var can be used.
var ItemDict = ...
Because SceneControllerState_string is defined between { }, it only exists between the { } meaning it won’t exist later on when you try to use it outside of the else clause.
Per the docs, it’s event.itemName. The state is event.itemState so you don’t really need to pull it from the Item itself and in fact it’s better not to as the Item may have already changed state.
But I hope you can see that in the long run, even option 1 above with 32 separate but very simple rules will be easier to maintain than one really complicated rule with a dit of arrays or arrays and all sorts of logic to define the scenes.

