No, I write all my rules in JavaScript with a personal library as well as a public library that I maintain for the community. Most of my complicated rules have been turned into rule templates for anyone to review, learn from, or just install and use.
In actuality, I rewrote all my rules in Jython years ago (around OH 2.3 I think). When Jython support was late to coming to OH 3 I rewrote them again in Nashorn Java Script. Finally, when I was able to convince the JS Scripting add-on developers to add some features to the add-on to make it more friendly to UI rules writers I updated my rules to JS Scripting. I’ve never used Blockly for anything beyond what I’ve done to help users on the forum.
But, having said that, yes, I’d prefer Blockly over Rules DSL at this point. It is more complete (Rules DSL cannot access Item metadata, call another rule, etc.), it’s typing is less half-assed and consistent, and it supports common programming concepts like real functions, external libraries, etc.
When it was a choice between Rules DSL and one of the JSR223 languages, yes, I was an advocate for Rules DSL, especially for new users who are not already programmers. However, now that we have better support for third party languages with the helper libraries coming with the add-on and we have a more beginner friendly yet more complete coding environment with Blockly, I can’t recommend Rules DSL for anything but legacy.
For reference, here is how I would write your rule as a UI rule using JS Scripting
configuration: {}
triggers:
- id: "1"
configuration:
itemName: XinezCallState
state: OFF
type: core.ItemCommandTrigger
conditions:
- inputs: {}
id: "3"
configuration:
itemName: Vanja
state: ON
operator: =
type: core.ItemStateCondition
actions:
- inputs: {}
id: "3"
label: Update call state
description: Sets Mute to ON or OFF based on call state and presence
configuration:
type: application/javascript
script: >
if(["OFFHOOK", "RINGING"].contains(event.receivedCommand.toString())) {
items.Mute.sendCommandIfDifferent("ON");
}
else if(events.receivedCommand.toString() == "IDLE") {
items.Mute.sendCommandIfDifferent(OFF");
}
type: script.ScriptAction
This uses the “But only if…” clause in UI rules so the rule only runs if Vanja is ON, making it so we don’t have to check for that in the script action. I also reordered the checks to simplify the if conditions and reduce duplicated code.
Note, all you would “code” in the above is the script action. The rest gets created when you create the rule.
Given the simplicity of this rule I might choose between a number of different representations in a .js file.
JSRule which will be closer to what you are used to in Rules DSL:
rules.JSRule({
name: "Vanja Call State",
description: "Mutes based on call status",
triggers: [triggers.ItemCommandTrigger('XinezCallState')],
execute: (event) => {
if(items.Vanja.state != "ON") return;
if(["OFFHOOK", "RINGING"].contains(event.receivedCommand.toString()) {
items.Mute.sendCommandIfDiffernt("ON");
}
else if(event.receivedCommand.toString() == "IDLE") {
items.Mute.sendCommandIfDifferent("OFF");
}
},
tags: [],
id: "vanja-call-state"
});
Or using rule builder:
rules.when().item("XinezCallState").receivedCommand()
.if().itemState("Vanja").is("ON")
.then((event) => {
if(["OFFHOOK", "RINGING"].contains(event.receivedCommand.toString()) {
items.Mute.sendCommandIfDiffernt("ON");
}
else if(event.receivedCommand.toString() == "IDLE") {
items.Mute.sendCommandIfDifferent("OFF");
}
})
.build("Vanja Call State", "Mutes based on call status", [], "vanja-call-state");
Or it could be simpler if we break it into two rules:
rules.when().item("XinezCallState").receivedCommand()
.if().itemState("Vanja").is("ON")
.if().itemState("Mute").is("OFF")
.if((event) => ["OFFHOOK", "RINGING"].contains(event.receivedCommand.toString()))
.then().sendOn("Mute")
.build("Vanja Mute Call State", "Mutes based on OFFHOOK and RINGING", [], "vanja-call-state-mute");
rules.when().item("XinezCallState").receivedCommand()
.if().itemState("Vanja").is("ON")
.if().itemState("Mute").is("ON")
.if((event) => "IDLE" == event.receivedCommand.toString())
.then().sendOff("Mute")
.build("Vanja Unmute Call State", "Unmutes based on IDLE", [], "vanja-call-state-unmute");
Note, all of these examples are just typed in. They almost certainly contain typos and may not work as written. I don’t write rules in text files so I’m making some assumptions on how things work, particularly with the rule builder examples.