The Dead Man’s Switch Design Pattern might be applicable here.
The tl;dr is you set a flag which remains one value by default but temporarily gets set to another value while the rule is executing. You use this to tell the difference between a command sent by a rule verses one sent by physically switching the device.
That is basically what @dan12345 is proposing. The article above is a bit more complex and involved but has more explanation.
See the Group and Loop Design pattern, specifically the “TimeOfDay” changed rule, and see if something like that could be leveraged.
In short you would define a Group for each scene and Items to store the states for those scenes. If all your Items are named in such a way that they can be constructed in the rule you can pull out the custom setting Item for the light within the forEach loop using a filter.
For example:
gNightScene.members.forEach[light |
if(light.state as ColorType != new ColorType(0,0,0)) { // dimmer set to 0
light.sendCommand(gNightSceneSettings.members.filter[s|s.name == light.name+"_Night_Setting"].state)
]
NOTE: I just typed in the above, I don’t know if that is how ColorType is initialized. But I do know when you have a Color Item, even though you can send it Dimmer or OnOff commands, internally it stores it as a ColorType so 0,0,0 == Dimmer 0 == OFF meaning to see if the light is OFF you need to check for 0,0,0.
The latency is a problem and one unfortunately difficult to address. Some users have seen huge speedups by using JSR233 and Jython for the rules that need to run really fast. There are other tricks one can use to get them really close together but none of them are really proven.