This sentence contains an infinity of possibilities. What doesn’t work? Errors in the logs? ![]()
Are you trying to make a function that returns a value?
A block literally just copies the code in the template into the place where you put the block on the screen. If you want to create a function you need to define the function as a utility and then in the template call the function from the utility.
For example, I have the following utility in my OHRT block library.
- component: UtilityFunction
config:
code: >
function {{name}}(cache, name) {
return {{getOrInstantiate}}(cache, name, null, () => {{OHRT}}.TimerMgr());
}
name: getTimerMgr
And then in the template I have
- component: UtilityFunction
config:
code: |
var {{name}} = (() => {
const ohrt = require('openhab_rules_tools');
ohrt.helpers.validateLibraries('4.1.0', '2.0.3');
return ohrt;
})();
name: OHRT
- component: UtilityFunction
config:
code: >
function {{name}}(cache, name, condition, create) {
condition = (condition === undefined || condition === null) ? ((manager) => false) : condition;
let manager = cache.get(name);
if(manager === null || condition(manager)) {
manager = create();
cache.put(name, manager);
}
return manager;
}
name: getOrInstantiate
- component: BlockCodeTemplate
config:
template: >
{{utility:getTimerMgr}}(cache.{{field:CACHE}},
{{input:TIMER_MGR_NAME}}).check({{input:TIMER_KEY}}, 'PT' +
{{input:DURATION}} + '{{field:UNIT}}',
function() { {{statements:TIMER_FUNC}} },'{{field:RESCHDULE}}' == 'TRUE',
function() { {{statements:FLAPPING_FUNC}} }, {{input:TIMER_KEY}});
The generated code looks like this:
var loopCount, loopCount2, startTime;
function getOrInstantiate(cache, name, condition, create) {
condition = (condition === undefined || condition === null) ? ((manager) => false) : condition;
let manager = cache.get(name);
if(manager === null || condition(manager)) {
manager = create();
cache.put(name, manager);
}
return manager;
}
var OHRT = (() => {
const ohrt = require('openhab_rules_tools');
ohrt.helpers.validateLibraries('4.1.0', '2.0.3');
return ohrt;
})();
function getTimerMgr(cache, name) {
return getOrInstantiate(cache, name, null, () => OHRT.TimerMgr());
}
getTimerMgr(cache.private, 'timerMgr').check('foo', 'PT' + 5 + 'S',
function() { console.info('timer expired'); },'TRUE' == 'TRUE',
function() { console.info('flapping'); }, 'foo');
A UtilityFunction will only be inserted into the code once even if you add the block multiple times. And then where you inserted the block a call to the function will be added to the code.
All of my blocks need to import the OHRT library but even if you drop a bunch of blocks into a script, the OHRT block of code will only be inserted once, and this is self calling function.
getOrInstantiate will pull a Object from the cache or create a new Object if there isn’t one. This is used by all the blocks that use the cache but again, even if I include a bunch of such blocks, there will be only the one getOrInstantiate function added to the code.
getTimerMgr is a function that calls getOrInstantiate to create the TimerMgr Object. This shows how a UtilityFunction can call another one.
Note that there is a separate utilities section in the YAML that goes after and at the same level as the “block” section under “slots”. You can see my full block library at openHAB Rules Tools [4.1.0.0;5.9.9.9] for reference, though many of the others are probably simpler examples.