No, 100% Blockly.
The YAML shows the full Rule. It’s what you’d see if you clicked on the “Code” tab of the rule. You see all the triggers, conditions and actions in context this way.
Create a rule, copy that YAML and paste it into the code tab and you’ll have a copy of the whole rule.
The only “code” are the two blockly scripts I pasted screen shots into above. All that “blockSource” stuff is what those graphics turn into for storage and the script stuff is what the Blockly compiles into. But all you need to worry about is the graphical Blockly scripts.
Create a Blockly rule and click on the code tab and you’ll see something similar for any of your rules.
If I were to write this as JS Scripting it would look something like this:
configuration: {}
triggers:
- id: "1"
configuration:
cronExpression: "* * * * * ? *"
type: timer.GenericCronTrigger
conditions:
- inputs: {}
id: "2"
configuration:
type: application/javascript
script: >
time.toZDT().isBetween(time.toZDT(items.Default_Day), time.toZDT('23:00');
type: script.ScriptCondition
actions:
- inputs: {}
id: "3"
configuration:
type: application/javascript
script: |
newCommand = (items.FamilyRoomOutlet.state == 'OFF') ? 'ON' : 'OFF';
items.getItem('FamilyRoomOutlet').sendCommand(newCommand);
items.getItem('FamilyRoomOutlet').sendCommand(newCommand);
type: script.ScriptAction
It’s the rule trigger.
`* * * * * ? *
In the YAML above it’s this part:
triggers:
- id: "1"
configuration:
cronExpression: "* * * * * ? *"
type: timer.GenericCronTrigger
There is a cron builder in MainUI.
In MainUI it would be:
As a DSL Rule as a file based rule trigger:
rule "Weather lights blinking"
when
Time cron "* * * * * ? *"
then
...
end
The rule triggers every second do there is no reference to it in the Blockly. It’s handled by the rule trigger.
Blockly doesn’t use cron. That’s a rule trigger thing.
If I break it down:
configuration: {}
This is usually empty unless the rule was created from a rule template.
triggers:
- id: "1"
configuration:
cronExpression: "* * * * * ? *"
type: timer.GenericCronTrigger
These are the rule triggers. This is a cron trigger that runs this rule every second. This is your cron expression. No Blockly involved.
conditions:
- inputs: {}
id: "2"
configuration:
blockSource: <xml xmlns="https://developers.google.com/blockly/xml"><block
type="oh_zdt_between" id="PHU!!N)WV2]uo2LH@4_b" x="14" y="29"><field
name="dateComparison">time</field><value name="zdtOne"><shadow
type="oh_zdt" id=")K452c,b^!b=tbUCx;=o"><field
name="day">2023-11-21</field></shadow><block type="oh_zdt_now"
id="8[,apY14USqj/lqOH%ON"></block></value><value name="zdtTwo"><shadow
type="oh_zdt" id="/M%!MCCi:u:^bfqioyK~"><field
name="day">2023-11-21</field></shadow><block type="oh_zdt_fromItem"
id="3,rxp4*)cLLb}sB7)C-^"><value name="itemName"><shadow type="oh_item"
id="%~n1xA84JGAeFgGE[2pG"><mutation itemName="MyItem"
itemLabel="MyItem"></mutation><field
name="itemName">MyItem</field></shadow><block type="oh_item"
id="%~n1xA84JGAeFgGE[2pG"><mutation itemName="Default_Day"
itemLabel="Default Day"></mutation><field
name="itemName">Default_Day</field></block></value></block></value><value
name="zdtThree"><shadow type="oh_zdt" id="SCE81J(9-s#xRDL}p8k)"><field
name="day">2023-11-21</field></shadow><block type="oh_zdt_create"
id="G,DrwHR?-`+J|v9u@K5V"><value name="year"><shadow type="math_number"
id="R#cJKC@)d|-BGQx*wi%1"><field
name="NUM">2005</field></shadow></value><value name="month"><shadow
type="math_number" id="zNhg.H[*Z%+_qL}^$B%:"><field
name="NUM">4</field></shadow></value><value name="day"><shadow
type="math_number" id="ms(?|}iyqRQ`*7u?xSt?"><field
name="NUM">12</field></shadow></value><value name="hour"><shadow
type="math_number" id="QREb_kY_K{(a5#g)(tsY"><field
name="NUM">23</field></shadow></value><value name="minute"><shadow
type="math_number" id="TQ!i9ycS;4A1:A~I$x8f"><field
name="NUM">10</field></shadow><block type="math_number"
id="TQ!i9ycS;4A1:A~I$x8f"><field
name="NUM">0</field></block></value><value name="second"><shadow
type="math_number" id="4iy#_N,i,vzVTGK`#%DI"><field
name="NUM">58</field></shadow><block type="math_number"
id="4iy#_N,i,vzVTGK`#%DI"><field
name="NUM">0</field></block></value></block></value></block></xml>
type: application/javascript
script: >
// graalVM
function zdtCompare(zdt1, zdt2, compareOp, precision, compDate) {
switch (precision) {
case 'years':
zdt2 = zdt2.withMonth(zdt1.monthValue());
case 'months':
zdt2 = zdt2.withDayOfMonth(zdt1.dayOfMonth());
case 'days':
zdt2 = zdt2.withHour(zdt1.hour());
case 'hours':
zdt2 = zdt2.withMinute(zdt1.minute());
case 'minutes':
zdt2 = zdt2.withSecond(zdt1.second());
case 'seconds':
zdt2 = zdt2.withNano(zdt1.nano());
}
if (compDate === 'date') {
zdt1 = zdt1.toLocalDate();
zdt2 = zdt2.toLocalDate();
} else if (compDate === 'time') {
zdt1 = zdt1.toLocalTime();
zdt2 = zdt2.toLocalTime();
}
switch (compareOp) {
case 'before':
return zdt1.isBefore(zdt2);
case 'equal':
return zdt1.equals(zdt2);
case 'after':
return zdt1.isAfter(zdt2);
case 'beforeEqual':
return zdt1.isBefore(zdt2) || zdt1.equals(zdt2);
case 'afterEqual':
return zdt1.isAfter(zdt2) || zdt1.equals(zdt2);
}
}
(time.ZonedDateTime.now()).isBetweenTimes((time.toZDT(items.getItem('Default_Day'))), time.ZonedDateTime.now().withYear(2005).withMonth(4).withDayOfMonth(12).withHour(23).withMinute(0).withSecond(0).withNano(0));
type: script.ScriptCondition
This is the Script Condition. It’s a whole lot of text in the YAML but you don’t have to worry about that. In the UI it’s just
Even though the rule triggers every second all day long, this only runs the script actions if now is between the time stored in the Item Default_Day
and 23:00
. Only the time is compared so you can ignore the date part.
The XML at the top defines the “blocks” that make up the script condition. The JavaScript at the bottom is what the Blocks turn into to run.
actions:
- inputs: {}
id: "3"
configuration:
blockSource: <xml
xmlns="https://developers.google.com/blockly/xml"><variables><variable
id="1HSiEMy:fL^_2~;Svj~F">newCommand</variable></variables><block
type="variables_set" id="#RN1dgP^c{T$tbK%BhI`" x="37" y="25"><field
name="VAR" id="1HSiEMy:fL^_2~;Svj~F">newCommand</field><value
name="VALUE"><block type="text" id="iG9-:i]jr6A5[!-emfLS"><field
name="TEXT">OFF</field></block></value><next><block type="controls_if"
id="O.%2G2P3ZN/=#vqEm*{|"><value name="IF0"><block type="logic_compare"
id="RE_Ck%2oG~3f-;mj!u-m"><field name="OP">EQ</field><value
name="A"><block type="oh_getitem_attribute"
id="?)Q(iMNG[Ui3rdW![YJ,"><mutation
attributeName="State"></mutation><field
name="attributeName">State</field><value name="item"><shadow
type="oh_getitem" id="iZ@.SUf=sP}ub{mj|xXv"><value
name="itemName"><shadow type="oh_item"
id="omk.nh-?FTaOIJSNDKQ@"><mutation itemName="MyItem"
itemLabel="MyItem"></mutation><field
name="itemName">MyItem</field></shadow></value></shadow><block
type="oh_getitem" id="iZ@.SUf=sP}ub{mj|xXv"><value
name="itemName"><shadow type="oh_item"
id="omk.nh-?FTaOIJSNDKQ@"><mutation itemName="MyItem"
itemLabel="MyItem"></mutation><field
name="itemName">MyItem</field></shadow><block type="oh_item"
id="omk.nh-?FTaOIJSNDKQ@"><mutation itemName="FamilyRoomOutlet"
itemLabel="Family Room Lamp 1"></mutation><field
name="itemName">FamilyRoomOutlet</field></block></value></block></value></block></value><value
name="B"><block type="text" id="$72gM9~5{YuWLv`oPZ*W"><field
name="TEXT">OFF</field></block></value></block></value><statement
name="DO0"><block type="variables_set" id="CUb,1oLkwQZ8Nds8L!+h"><field
name="VAR" id="1HSiEMy:fL^_2~;Svj~F">newCommand</field><value
name="VALUE"><block type="text" id="R5V}NI:t[FxfLyS!6!xZ"><field
name="TEXT">ON</field></block></value></block></statement><next><block
type="oh_event" id="Kn;+(xN:@KA?Flr_JTa$"><field
name="eventType">sendCommand</field><value name="value"><shadow
type="text" id="4W7Rfux)nlpB7IzV^6:j"><field
name="TEXT">value</field></shadow><block type="variables_get"
id="9H#Hh@|WH;W[MrAShPha"><field name="VAR"
id="1HSiEMy:fL^_2~;Svj~F">newCommand</field></block></value><value
name="itemName"><shadow type="oh_item"
id="-.+cj*C-.%)j3Cz{/8hD"><mutation itemName="MyItem"
itemLabel="MyItem"></mutation><field
name="itemName">MyItem</field></shadow><block type="oh_item"
id="-.+cj*C-.%)j3Cz{/8hD"><mutation itemName="FamilyRoomOutlet"
itemLabel="Family Room Lamp 1"></mutation><field
name="itemName">FamilyRoomOutlet</field></block></value><next><block
type="oh_event" id="=f7,|@Zk~9XHpH;*Z.M0"><field
name="eventType">sendCommand</field><value name="value"><shadow
type="text" id="=n0hvFrkFTGsIF]5xlY5"><field
name="TEXT">value</field></shadow><block type="variables_get"
id="sN.=S)FuD6N(hMt=JY}F"><field name="VAR"
id="1HSiEMy:fL^_2~;Svj~F">newCommand</field></block></value><value
name="itemName"><shadow type="oh_item"
id="w=!,IrP3P-;*ARK~S~.@"><mutation itemName="MyItem"
itemLabel="MyItem"></mutation><field
name="itemName">MyItem</field></shadow><block type="oh_item"
id="K,v^y3ns$AHklt4@h}w-"><mutation itemName="FamilyRoomOutlet"
itemLabel="Family Room Lamp 1"></mutation><field
name="itemName">FamilyRoomOutlet</field></block></value></block></next></block></next></block></next></block></xml>
type: application/javascript
script: |
var newCommand;
newCommand = 'OFF';
if (items.getItem('FamilyRoomOutlet').state == 'OFF') {
newCommand = 'ON';
}
items.getItem('FamilyRoomOutlet').sendCommand(newCommand);
items.getItem('FamilyRoomOutlet').sendCommand(newCommand);
type: script.ScriptAction
This is the script action. Again it’s a whole lot of text but in the UI you’d only see
When the rule is triggered and the condition allows the action to be run, this script will look to see if the light is already ON and turn it OFF, or if it’s already OFF it will turn it ON.
Therefore:
- Trigger: run once per second
- Condition: but only between Default_Day and 23:00
- Do: Toggle the lights ON or OFF
Screen Shots showing how you would copy/paste and how the rule looks in the UI.
Click the Code Tab and paste the YAML from above.
Return to the Design Tab.
The Trigger:
The Condition (But only if…):
The Action: