You can send Dimmer and Switch commands to a Color Item. Depending on how the MQTT communications work you may only need the Color Channel and Item.
That is the difference between a command and an update in OH. An update stays within OH. A command goes out to the binding and eventually out to the device.
Correct, the processing of the command is handled in parallel by the Item and the rule so it is not guaranteed that the command has caused the Item to change state when the rule is running. And really, there is no guarantee that the Item will ever change state in response to a command.
Pass arguments from where? Scripts that call scripts can certainly pass arguments to each other, even in Blockly.
What hasn’t been said is how comprehensive is this automation and where is it implemented? For example, if one maunally changes one light, does that disable the automation for just that one light, some of the lights, all of the lights? Is the automation managed by rules or on the devices themselve?
This is really a case of Design Pattern: Manual Trigger Detection which documents a couple of approaches for detecting where a command or event is comming from. The proxy Item is the most reliable.
My automation is simple so I personally just disable the rule that detects manual triggers when the automation is changing the lights. Then I reenable it. That way the manual detection rule can treate any event as a manually triggered event and set a flag to indicate the automation has been overridden.
Once you can distinguish between automated commands/updates from manual commands/updates you have some options. You can set an Item to act as a flag and then use a rule condition (for managted rules) or if statement to cause your rules not to process the event when automation is disabled. You can also disable the automation rules entirely (not available in Rules DSL) so for all intents and purposes the rule doesn’t exist so can’t be triggered. When returning to auto mode reenable the rules.
My automation involves controlling the lights based on a calculated ambient light level. If one manually controls a light, automation is turned off for that light until the next day. The rules are here for an example:
-
Virtual Solar Light Sensor [4.0.0.0;4.9.9.9] for calculating the light level based on cloudiness and solar output
-
this rule turns on/off the lights based on the brightness claculated from the above, but only during the DAY time of day. This is the automation rule.
configuration: {}
triggers:
- id: "1"
configuration:
itemName: Outdoors_Weighted_Brightness
type: core.ItemStateChangeTrigger
- id: "2"
configuration:
itemName: TimeOfDay
state: DAY
type: core.ItemStateChangeTrigger
conditions:
- inputs: {}
id: "3"
configuration:
itemName: TimeOfDay
state: DAY
operator: =
type: core.ItemStateCondition
- inputs: {}
id: "6"
label: Outdoors_Weighted_Brightness isn't undefined
configuration:
type: application/javascript;version=ECMAScript-2021
script: |
!items.getItem('Outdoors_Weighted_Brightness').isUninitialized;
type: script.ScriptCondition
actions:
- inputs: {}
id: "4"
configuration:
type: application/javascript;version=ECMAScript-2021
script: >-
var lightState =
(items.Outdoors_Weighted_Brightness.quantityState.greaterThanOrEqual('25000
lx')) ? 'OFF' : 'ON';
console.debug('New light state is ' + lightState + ', adjusting the
lights accordingly');
console.debug('Disabling the override rule');
rules.setEnabled('weather_lights_override', false);
items.TOD_Lights_ON_WEATHER
.members
.filter(light => light.getMetadata('LightsOverride').value == 'false' || !light.getMetadata('LightsOverride').value)
.forEach(light => {
console.debug('Commanding ' + light.label + ' to ' + lightState + ' do to weather');
light.sendCommandIfDifferent(lightState);
});
setTimeout(() => {
console.debug('Reenabling override rule');
rules.setEnabled('weather_lights_override', true);
}, 250);
type: script.ScriptAction
- The manual trigger detection rule is relatively simple, treating any event as a manual event, setting the override flag (I use Item metadata as you can see from above).
configuration: {}
triggers:
- id: "1"
configuration:
groupName: TOD_Lights_ON_WEATHER
type: core.GroupStateChangeTrigger
conditions:
- inputs: {}
id: "3"
configuration:
itemName: TimeOfDay
state: DAY
operator: =
type: core.ItemStateCondition
actions:
- inputs: {}
id: "2"
configuration:
type: application/javascript;version=ECMAScript-2021
script: >
console.info('Manual light trigger detected, overriding the light for
{}', event.itemName);
items[event.itemName].replaceMetadata('LightsOverride', 'true', []);
type: script.ScriptAction
- Finally, I have a rule to reset the override flags so the automation runs as expected the next day.
configuration: {}
triggers:
- id: "1"
configuration:
itemName: TimeOfDay
previousState: DAY
type: core.ItemStateChangeTrigger
conditions: []
actions:
- inputs: {}
id: "2"
configuration:
type: application/javascript;version=ECMAScript-2021
script: "console.loggerName = 'org.openhab.automation.rules_tools.Reset Lights
Override';
console.info('Resetting the LightsOverride metadata value to false');
console.debug('Looping through the lights');
items.TOD_Lights_ON_WEATHER.members.forEach( light => {
\ console.debug('Current override for ' + light.name + ' is ' +
light.getMetadata('LightsOverride').value);
\ light.replaceMetadata('LightsOverride', 'false');
})
\ "
type: script.ScriptAction
Note: I’m noticing that there are some updates I can make to these rules to take advantage of changes since OH 3.x when I last looked at them.