Thank you!
I will look into this and see, how I can make use of your code.
@NCO sorry for resurecting this, but I was wondering if you had found a solution to display a “readable” list of things that were offline and if you would mind sharing it?
I know i resurect an old topic, but i think it complements nicely the Thing Status Reporting.
Thanks,
Sorry, I did not follow this path yet.
I had more urgent things to fix
update: Don’t use the following blockly example. There is a better one further down that uses the original marketplace rule from Rich.
Hi Rich (and @NCO, @thefathefa),
I changed/extended your rule a bit, especially since I wanted to see readable names (labels) of the offline things… but then I did a little bit more… Maybe you can use something for your next revision, or somebody else likes it. I thought the whole solution might be nice for the marketplace but I didn’t want to steal Rich’s code. Tell me if it’s better to start a new thread. The changes are:
- Filter all things that are not ONLINE or UNINITIALIZED (to see things with initialisation problems too. You get the things with status INITIALIZING, OFFLINE, REMOVED, REMOVING, UNKNOWN for further processing.
- Export of labels, IDs and status. (As far as I understand, the values of the context hashmap are passed as strings. Please tell me if there is a better way than passing as arrays)
- evaluation rule with Ignore-list for things to be skipped, that sends telegram messages when things are offline (love it).
Cron-rule with changes at the end
if(typeof(require) === "function") Object.assign(this, require('@runtime'));
var logger = Java.type("org.slf4j.LoggerFactory").getLogger("org.openhab.model.script.rules_tools.Thing Status Change");
var ThingStatus = Java.type("org.openhab.core.thing.ThingStatus");
var FrameworkUtil = Java.type("org.osgi.framework.FrameworkUtil");
var ScriptHandler = Java.type("org.openhab.core.automation.module.script.rulesupport.shared.ScriptedHandler");
var _bundle = FrameworkUtil.getBundle(ScriptHandler.class);
var bundle_context = _bundle.getBundleContext();
// Get the Thing Regsitry
var classname = "org.openhab.core.thing.ThingRegistry";
var ThingRegistry_Ref = bundle_context.getServiceReference(classname);
var ThingRegistry = bundle_context.getService(ThingRegistry_Ref);
// Get the RuleManager
var classname = "org.openhab.core.automation.RuleManager"
var RuleManager_Ref = bundle_context.getServiceReference(classname);
var RuleManager = bundle_context.getService(RuleManager_Ref);
var things_Label = []
var things_Id = []
var things_Status = []
// Get Things that are not online
ThingRegistry.stream().filter(function(t) {
return (t.getStatus() != ThingStatus.ONLINE) && (t.getStatus() != ThingStatus.UNINITIALIZED)
})
.forEach (function(t) {
things_Label.push (t.getLabel() );
things_Id.push (t.getUID().getId() );
things_Status.push (t.getStatus() );
})
logger.debug("There are " + things_Id.length + " things that are not online");
// Call the handler rule with the lists of IDs, Labels and status
if (things_Id.length > 0) {
var data = new java.util.HashMap();
data.put("id", things_Id);
data.put("label", things_Label);
data.put("status", things_Status);
RuleManager.runNow("Alarm_offlineThing", true, data);
}
else {
logger.debug("No items match the criteria");
}
evaluation rule (blockly). To use paste it in the code tab of an empty rule
configuration: {}
triggers: []
conditions: []
actions:
- inputs: {}
id: "1"
configuration:
blockSource: "<xml
xmlns=\"https://developers.google.com/blockly/xml\"><variables><variable
id=\"]8Kt_8cXjoij*UWfL]}Z\">ignore</variable><variable
id=\"Qzn]o6PxTzj]cn8bnT2k\">messageText</variable><variable
id=\"de)1$u9v),E:|(s({PVw\">list_label</variable><variable
id=\":mi-th}K]jPfbR.cd|8t\">list_id</variable><variable
id=\"QE1Tf`(su?=)z/IvG]Ml\">list_status</variable><variable
id=\"E@l+)XgabtaQN$-j#0}]\">i</variable></variables><block
type=\"variables_set\" id=\"A`J${j$nZ_dOHC]+d`GI\" x=\"-42\"
y=\"-352\"><field name=\"VAR\"
id=\"]8Kt_8cXjoij*UWfL]}Z\">ignore</field><value name=\"VALUE\"><block
type=\"text\" id=\"i:tQdMWT($M2/|(JSPl9\"><field
name=\"TEXT\">Example_ID_1,
Example_ID_2</field></block></value><next><block type=\"variables_set\"
id=\"0vV{KknuF_oq_@1;-c5s\"><field name=\"VAR\"
id=\"Qzn]o6PxTzj]cn8bnT2k\">messageText</field><value
name=\"VALUE\"><block type=\"text\" id=\"hD-daeK:-q]Hoi{~lbW;\"><field
name=\"TEXT\"></field></block></value><next><block type=\"oh_log\"
id=\"V67tNp:rbdm+Y}L/x,4o\"><field name=\"severity\">debug</field><value
name=\"message\"><shadow type=\"text\"
id=\"i77BH#sZ2AL=2nNh=4Hb\"><field
name=\"TEXT\">abc</field></shadow><block type=\"oh_context_attribute\"
id=\"ItP}])9xOd?Z/v6/F)Py\"><value name=\"key\"><shadow type=\"text\"
id=\"8=q=T@jmhGwC1D2tk#uR\"><field
name=\"TEXT\">label</field></shadow></value></block></value><next><block
type=\"variables_set\" id=\"GR{vZ946}Ug;S8z_N.Wz\"><field name=\"VAR\"
id=\"de)1$u9v),E:|(s({PVw\">list_label</field><value
name=\"VALUE\"><block type=\"lists_split\"
id=\"*zsq,7yH1Fr0x9~3-Y7B\"><mutation mode=\"SPLIT\"></mutation><field
name=\"MODE\">SPLIT</field><value name=\"INPUT\"><block
type=\"text_join\" id=\"P1QH8RtkOeX/I:c?A+U5\"><mutation
items=\"1\"></mutation><value name=\"ADD0\"><block
type=\"oh_context_attribute\" id=\"LTWWl(QN-P|L`2DSuXC(\"><value
name=\"key\"><shadow type=\"text\" id=\"tSoTPJD=s.K5TvwBe6?:\"><field
name=\"TEXT\">label</field></shadow></value></block></value></block></v\
alue><value name=\"DELIM\"><shadow type=\"text\"
id=\"/AtCJEyGz0h|#Q}SBhrK\"><field
name=\"TEXT\">,</field></shadow></value></block></value><next><block
type=\"variables_set\" id=\"!n@S={3Jr8hQo%JI9Hub\"><field name=\"VAR\"
id=\":mi-th}K]jPfbR.cd|8t\">list_id</field><value name=\"VALUE\"><block
type=\"lists_split\" id=\"h5wDS.dtQKismlHuoE1_\"><mutation
mode=\"SPLIT\"></mutation><field name=\"MODE\">SPLIT</field><value
name=\"INPUT\"><block type=\"text_join\"
id=\"uYIGn3P(N)O9%sHsp8j%\"><mutation items=\"1\"></mutation><value
name=\"ADD0\"><block type=\"oh_context_attribute\"
id=\"l#C@M/Ub^GGiWD=cVMe{\"><value name=\"key\"><shadow type=\"text\"
id=\"jL;|RlACo:TcppnI4AD}\"><field
name=\"TEXT\">id</field></shadow></value></block></value></block></valu\
e><value name=\"DELIM\"><shadow type=\"text\"
id=\"w-+J+}+Bkj~[EPr_J=cF\"><field
name=\"TEXT\">,</field></shadow></value></block></value><next><block
type=\"variables_set\" id=\"fLS9V8Tnb[Tm@tS5d^k!\"><field name=\"VAR\"
id=\"QE1Tf`(su?=)z/IvG]Ml\">list_status</field><value
name=\"VALUE\"><block type=\"lists_split\"
id=\"!h`%(OE44#P7d!yBEb_%\"><mutation mode=\"SPLIT\"></mutation><field
name=\"MODE\">SPLIT</field><value name=\"INPUT\"><block
type=\"text_join\" id=\"[%1U++k%0%ewT/EkZCB}\"><mutation
items=\"1\"></mutation><value name=\"ADD0\"><block
type=\"oh_context_attribute\" id=\"POH;[%EDtuu,]/#XI_`t\"><value
name=\"key\"><shadow type=\"text\" id=\"ehDvr7dus+oWwpRZccc%\"><field
name=\"TEXT\">status</field></shadow></value></block></value></block></\
value><value name=\"DELIM\"><shadow type=\"text\"
id=\"o7rTo-ZZMr4V0w--gl_S\"><field
name=\"TEXT\">,</field></shadow></value></block></value><next><block
type=\"controls_for\" id=\"a%PPQ=;_xNd:W6v}}f5[\"><field name=\"VAR\"
id=\"E@l+)XgabtaQN$-j#0}]\">i</field><value name=\"FROM\"><shadow
type=\"math_number\" id=\"asvPqe~e|*?MZKV+Ldyl\"><field
name=\"NUM\">1</field></shadow></value><value name=\"TO\"><shadow
type=\"math_number\" id=\"mGf:6L7d*iJfact;;=AZ\"><field
name=\"NUM\">10</field></shadow><block type=\"lists_length\"
id=\"2h31}(uN6Y.nCua7$zpL\"><value name=\"VALUE\"><block
type=\"variables_get\" id=\"9BNtfh^bi`G9?.5+L#xL\"><field name=\"VAR\"
id=\":mi-th}K]jPfbR.cd|8t\">list_id</field></block></value></block></va\
lue><value name=\"BY\"><shadow type=\"math_number\"
id=\"^8;vyoQ8C5rx{J}n]4_k\"><field
name=\"NUM\">1</field></shadow></value><statement name=\"DO\"><block
type=\"oh_log\" id=\"6[A;2a`PzE:W2hE],=7b\"><field
name=\"severity\">info</field><value name=\"message\"><shadow
type=\"text\" id=\"TZIr.27H$*;W#JE]7ZZy\"><field
name=\"TEXT\">abc</field></shadow><block type=\"lists_getIndex\"
id=\"mkBmXfyc5+0$Nc}wPROP\"><mutation statement=\"false\"
at=\"true\"></mutation><field name=\"MODE\">GET</field><field
name=\"WHERE\">FROM_START</field><value name=\"VALUE\"><block
type=\"variables_get\" id=\"pPf+EO7#plsGN.tE_Gmj\"><field name=\"VAR\"
id=\":mi-th}K]jPfbR.cd|8t\">list_id</field></block></value><value
name=\"AT\"><block type=\"variables_get\"
id=\"Q4AV~M?C`kpaBUc1bQX#\"><field name=\"VAR\"
id=\"E@l+)XgabtaQN$-j#0}]\">i</field></block></value></block></value><n\
ext><block type=\"controls_if\" id=\"7.Kl=xcVc6TJI/EK80-G\"><value
name=\"IF0\"><block type=\"logic_compare\" id=\"4XmvLDcX@(]BPi]YBkR#\"
inline=\"false\"><field name=\"OP\">EQ</field><value name=\"A\"><block
type=\"text_indexOf\" id=\"pug+5L}uk22)e,PME/M;\"><field
name=\"END\">FIRST</field><value name=\"VALUE\"><block
type=\"variables_get\" id=\"#oba*+x9eth:Hv:X!@c}\"><field name=\"VAR\"
id=\"]8Kt_8cXjoij*UWfL]}Z\">ignore</field></block></value><value
name=\"FIND\"><shadow type=\"text\" id=\"44R*w).I5vC5Jj(o$n^J\"><field
name=\"TEXT\">abc</field></shadow><block type=\"lists_getIndex\"
id=\"-n8Z/Og:$NP^[F,hL#Wc\"><mutation statement=\"false\"
at=\"true\"></mutation><field name=\"MODE\">GET</field><field
name=\"WHERE\">FROM_START</field><value name=\"VALUE\"><block
type=\"variables_get\" id=\"2`Y6V-Kr@XebR_SS2c`+\"><field name=\"VAR\"
id=\":mi-th}K]jPfbR.cd|8t\">list_id</field></block></value><value
name=\"AT\"><block type=\"variables_get\"
id=\"pVu.PDdX[GNA*;f4.R4H\"><field name=\"VAR\"
id=\"E@l+)XgabtaQN$-j#0}]\">i</field></block></value></block></value></\
block></value><value name=\"B\"><block type=\"math_number\"
id=\"(XcAptJ%G7LLIfyz!ywF\"><field
name=\"NUM\">0</field></block></value></block></value><statement
name=\"DO0\"><block type=\"text_append\"
id=\"-6+nO0pA`L|8efOG2{PO\"><field name=\"VAR\"
id=\"Qzn]o6PxTzj]cn8bnT2k\">messageText</field><value
name=\"TEXT\"><shadow type=\"text\" id=\"P5=(ge5fi5^{59q]jiCS\"><field
name=\"TEXT\"></field></shadow><block type=\"text_join\"
id=\"6FMD8J.XGVB#Hv8fe{hP\"><mutation items=\"8\"></mutation><value
name=\"ADD0\"><block type=\"oh_text_crlf\"
id=\"|T1A/qty_!,q/ENHq~sz\"></block></value><value name=\"ADD1\"><block
type=\"text\" id=\"7c=`LG4uz455s*ilSHb2\"><field
name=\"TEXT\">____________________________</field></block></value><value
name=\"ADD2\"><block type=\"oh_text_crlf\"
id=\"j3lKb_(%g$3_1a:+j`rI\"></block></value><value name=\"ADD3\"><block
type=\"lists_getIndex\" id=\"s60t+$D!3#hd9}J;_!yS\"><mutation
statement=\"false\" at=\"true\"></mutation><field
name=\"MODE\">GET</field><field name=\"WHERE\">FROM_START</field><value
name=\"VALUE\"><block type=\"variables_get\"
id=\"5]cha6#4,r6l`Cm]y)Cp\"><field name=\"VAR\"
id=\"de)1$u9v),E:|(s({PVw\">list_label</field></block></value><value
name=\"AT\"><block type=\"variables_get\"
id=\"l4-k0q8h+SPCJ0KNX6O,\"><field name=\"VAR\"
id=\"E@l+)XgabtaQN$-j#0}]\">i</field></block></value></block></value><v\
alue name=\"ADD4\"><block type=\"text\"
id=\")Ul2AieSM5@w5zt/3$wW\"><field name=\"TEXT\">
(</field></block></value><value name=\"ADD5\"><block
type=\"lists_getIndex\" id=\"*4brwi?ZNr8;@[dp|nyI\"><mutation
statement=\"false\" at=\"true\"></mutation><field
name=\"MODE\">GET</field><field name=\"WHERE\">FROM_START</field><value
name=\"VALUE\"><block type=\"variables_get\"
id=\"`H`txBv]S|c^,NE92XDI\"><field name=\"VAR\"
id=\":mi-th}K]jPfbR.cd|8t\">list_id</field></block></value><value
name=\"AT\"><block type=\"variables_get\"
id=\"XBkzkQk[DUL:#9zDa*Vl\"><field name=\"VAR\"
id=\"E@l+)XgabtaQN$-j#0}]\">i</field></block></value></block></value><v\
alue name=\"ADD6\"><block type=\"text\"
id=\"@PD=Nz#q_S]EOyzv@{Y}\"><field name=\"TEXT\">):
</field></block></value><value name=\"ADD7\"><block
type=\"lists_getIndex\" id=\"*emnJot)d@7*H-}]]omZ\"><mutation
statement=\"false\" at=\"true\"></mutation><field
name=\"MODE\">GET</field><field name=\"WHERE\">FROM_START</field><value
name=\"VALUE\"><block type=\"variables_get\"
id=\"z.#(n#(~Bj++-MrL/,D!\"><field name=\"VAR\"
id=\"QE1Tf`(su?=)z/IvG]Ml\">list_status</field></block></value><value
name=\"AT\"><block type=\"variables_get\"
id=\"j3$=Ok..vpBRQm7c{q1l\"><field name=\"VAR\"
id=\"E@l+)XgabtaQN$-j#0}]\">i</field></block></value></block></value></\
block></value></block></statement></block></next></block></statement><n\
ext><block type=\"controls_if\" id=\"4l=bGRXqL*m#4st3WbIV\"><value
name=\"IF0\"><block type=\"variables_get\"
id=\"}eT[MPm),_,qbA._-|nz\"><field name=\"VAR\"
id=\"Qzn]o6PxTzj]cn8bnT2k\">messageText</field></block></value><stateme\
nt name=\"DO0\"><block type=\"telegram_with_chatID_message\"
id=\"%?.)2$rZJ)1$`[CGZ9qP\" inline=\"false\"><value
name=\"MESSAGE\"><shadow type=\"text\"
id=\"%jIrNi@b+!)=WA-_P8,8\"><field name=\"TEXT\">What's
up?</field></shadow><block type=\"text_join\"
id=\"+:B^y;:|mtkaD2WvQ-/;\"><mutation items=\"2\"></mutation><value
name=\"ADD0\"><block type=\"text\" id=\"Vq%.RspM!Sb]4j|oA!Yq\"><field
name=\"TEXT\">*Things not online:*</field></block></value><value
name=\"ADD1\"><block type=\"variables_get\"
id=\";tdF%Ltj{[p+U`Yxi09~\"><field name=\"VAR\"
id=\"Qzn]o6PxTzj]cn8bnT2k\">messageText</field></block></value></block>\
</value><value name=\"BOT\"><shadow type=\"oh_thing\"
id=\"!e*,mpQ{}pF?C[R{m==`\"><field
name=\"thingUid\">telegram:telegramBot:Telegram-Bot</field></shadow></v\
alue><value name=\"CHAT_ID\"><shadow type=\"math_number\"
id=\"Atq3IW%ItA[[RXD}bR/0\"><field
name=\"NUM\">-123</field></shadow></value></block></statement\
></block></next></block></next></block></next></block></next></block></\
next></block></next></block></next></block></xml>"
type: application/javascript
script: >
var ignore, messageText, list_label, list_id, list_status, i;
var logger = Java.type('org.slf4j.LoggerFactory').getLogger('org.openhab.rule.' + ctx.ruleUID);
var things = Java.type('org.openhab.core.model.script.actions.Things');
ignore = 'Example_ID_1, Example_ID_2';
messageText = '';
logger.debug(ctx['label']);
list_label = String(ctx['label']).split(',');
list_id = String(ctx['id']).split(',');
list_status = String(ctx['status']).split(',');
var i_end = list_id.length;
var i_inc = 1;
if (1 > i_end) {
i_inc = -i_inc;
}
for (i = 1; i_inc >= 0 ? i <= i_end : i >= i_end; i += i_inc) {
logger.info((list_id[(i - 1)]));
if (ignore.indexOf(list_id[(i - 1)]) + 1 == 0) {
messageText += String(['\r\n','____________________________','\r\n',list_label[(i - 1)],' (',list_id[(i - 1)],'): ',list_status[(i - 1)]].join(''));
}
}
if (messageText) {
things.getActions('telegram', 'telegram:telegramBot:Telegram-Bot').sendTelegram(-123, '*Things not online:*' + String(messageText));
}
type: script.ScriptAction
The blocky rule should look like this. You need the telegram binding and the telegram-with-chat-ids blockly library from the marketplace. Finally you have to change the bot and chat-id to your needs (see doc of telegram binding).
If everything works well the telegram message look like this:
Hope you like it. Comments/hints/improvements are welcome.
The original rule template supports this too. Choose ONLINE
for the status and !=
for the comparison.
This is why I pass the full Thing Object to the called script. With the Thing Object you have access to all of the properties of the Thing.
I think it’s better to keep it to passing the Thing Object because you get not just these three properties but access to all the Thing info like the Channels, location, properties, the ID of the bridge, and the ability to change the Thing (e.g. change the properties).
This is deliberately left as an exercise to the user to implement in the called rule. The end user writes a script to filter the list and send alerts or taking what ever remedial actions they want to take. That part is custom. The rule template should not make assumptions about what the user wants to do with the list of Things that match.
The rule that’s called can define a condition to only run when certain Things appear in the list. They are passed as a Map so all you need to do is check to see if the Thing ID you care about is in the keys.
Given this, I’m not seeing what this does differently beyond remove some capability from the original. Because it’s not a rule template, it cannot be installed and instantiated. The Thing status it looks for is hard coded. And it passes less information to the called rule. But it does show that there might be something I can do to improve this template’s use for Blockly users, but that needs to be in addition to, not in place of passing the Thing Object.
The Blockly rule you’ve posted is a good example of the sort of thing that can be done in response to being called though and with only minor modifications it should be able to work with the original, though you might need to use the script block to access the properties of the Thing Objects.
Note, when posting Blockly, post both a screen shot and the contents of the “code” tab in code fences.
```
code goes here
```
This rule template will be completely rewritten for OH 4 by porting it to ECMAScript 2021, taking advantage of the JS Scripting helper library and my own helper library, and possibly changing the triggers so it can run based on events rather than a polling period.
Generally speaking, if your goal is to suggest improvements to the original it’s proper to post here. If your goal is to provide an alternative to the original, it’s probably best to start a new thread. However, pay mind to the marketplace rules. The moderators want to avoid a proliferation of lots of alternative implementations of the same thing, confusing end users and making it difficult to keep track of. So it would probably be posted to the tutorials and solutions category.
I like the example for a script to be called by the original script in your blockly and it appears your aim is to improve the original script so I think it’s appropriate here.
Correct.
I tried but somehow could not access any properties in the called rule. That’s why I thought the object is not passed as a reference.
That’s basically what my called rule does, not in the condition but in the action.
I tried that, but .getLabel() returned nothing. But I’ll try again after the transfer to ecma 2021.
That’s what I did. You have the code collapsed under “…evaluation rule (blockly)…” above the screenshot (in code fences of course;).
Anyway, thanks for your reply and helpful hints.
In Blockly or a text based script action?
Post the code you tired so I can look into this further.
It was ecma 21 in text based script action.
Today I tried again in blockly and… it worked on the first try . I cannot tell what I did wrong.
Now it works with your template rule.
Here the code (for pasting in code-tab of new rule):
Click to see code
configuration: {}
triggers: []
conditions: []
actions:
- inputs: {}
id: "1"
configuration:
blockSource: "<xml
xmlns=\"https://developers.google.com/blockly/xml\"><variables><variable
id=\"]8Kt_8cXjoij*UWfL]}Z\">ignore</variable><variable
id=\"C,Wl8e|_BY7`@|WNRR)t\">things</variable><variable
id=\"Qzn]o6PxTzj]cn8bnT2k\">messageText</variable><variable
id=\"n0X6;%Q,_c=4$=`tHt^@\">ignoreList</variable><variable
id=\"%x2mOh`(Hd/#(A4O/k(]\">curThing</variable><variable
id=\"E%{F|_6VUVE]s;x=yceK\">thingId</variable><variable
id=\"oJm$Rz.ax{=5CWVHpP6o\">thingLabel</variable><variable
id=\"HrLFiEjH(SOud$zz{9iv\">thingStatus</variable></variables><block
type=\"oh_log\" id=\"{6Nhb|W/OGmd8@)Fp4@b\" disabled=\"true\" x=\"55\"
y=\"-618\"><field name=\"severity\">debug</field><value
name=\"message\"><shadow type=\"text\"
id=\"`*H5u4}v%f/UR]t5^Aqs\"><field name=\"TEXT\">Enter IDs to ignore in
next line (comma seperated)</field></shadow></value><next><block
type=\"variables_set\" id=\"A`J${j$nZ_dOHC]+d`GI\"><field name=\"VAR\"
id=\"]8Kt_8cXjoij*UWfL]}Z\">ignore</field><value name=\"VALUE\"><block
type=\"text\" id=\"i:tQdMWT($M2/|(JSPl9\"><field
name=\"TEXT\">example_ID1,exampleID2</field></block></value><next><block
type=\"variables_set\" id=\"{~WTIN2e_$f6q3SA6-Yv\"><field name=\"VAR\"
id=\"C,Wl8e|_BY7`@|WNRR)t\">things</field><value name=\"VALUE\"><block
type=\"oh_context_attribute\" id=\"|H7Nbd2VaPs{W;)0~AC?\"><value
name=\"key\"><shadow type=\"text\" id=\"K}t%;y/xn8{VP1ePVqF6\"><field
name=\"TEXT\">things</field></shadow></value></block></value><next><blo\
ck type=\"variables_set\" id=\"lI{JZ]zqeFw9P*HeI0t^\"><field
name=\"VAR\" id=\"Qzn]o6PxTzj]cn8bnT2k\">messageText</field><value
name=\"VALUE\"><block type=\"text\" id=\"/Let0^K`uHs}:3#7^N2p\"><field
name=\"TEXT\"></field></block></value><next><block
type=\"variables_set\" id=\"3Ld5v:`q))oi8DB;w=K?\"><field name=\"VAR\"
id=\"n0X6;%Q,_c=4$=`tHt^@\">ignoreList</field><value
name=\"VALUE\"><block type=\"lists_split\"
id=\"r3}xou^n;{KjY6dl0$RD\"><mutation mode=\"SPLIT\"></mutation><field
name=\"MODE\">SPLIT</field><value name=\"INPUT\"><block
type=\"variables_get\" id=\"(4kit^zIqe9-b/b7M4E*\"><field name=\"VAR\"
id=\"]8Kt_8cXjoij*UWfL]}Z\">ignore</field></block></value><value
name=\"DELIM\"><shadow type=\"text\" id=\"{CJs^j|p$=Y2x.Friu_p\"><field
name=\"TEXT\">,</field></shadow></value></block></value><next><block
type=\"oh_log\" id=\"V67tNp:rbdm+Y}L/x,4o\"><field
name=\"severity\">debug</field><value name=\"message\"><shadow
type=\"text\" id=\"i77BH#sZ2AL=2nNh=4Hb\"><field
name=\"TEXT\">abc</field></shadow><block type=\"oh_context_attribute\"
id=\"ItP}])9xOd?Z/v6/F)Py\"><value name=\"key\"><shadow type=\"text\"
id=\"8=q=T@jmhGwC1D2tk#uR\"><field
name=\"TEXT\">things</field></shadow></value></block></value><next><blo\
ck type=\"controls_forEach\" id=\"!*_/[dld@qMo~k.%wH8:\"><field
name=\"VAR\" id=\"%x2mOh`(Hd/#(A4O/k(]\">curThing</field><value
name=\"LIST\"><block type=\"variables_get\"
id=\"{;vLL.})j{+K}2-,fUf8\"><field name=\"VAR\"
id=\"C,Wl8e|_BY7`@|WNRR)t\">things</field></block></value><statement
name=\"DO\"><block type=\"oh_script_inline\"
id=\"dad|U8=9dRN@P@6#vrHj\"><field name=\"inlineScript\">thingLabel =
curThing.getLabel()&#10;thingId =
curThing.getUID().getId()&#10;thingStatus =
curThing.getStatus()</field><next><block type=\"controls_if\"
id=\"mxJbf8]-5BmqywT7W5sf\"><value name=\"IF0\"><block
type=\"logic_compare\" id=\"DAUiQW`ij2Yv[Dy$Fk.c\"
inline=\"false\"><field name=\"OP\">EQ</field><value name=\"A\"><block
type=\"lists_indexOf\" id=\"rv,~hIA.]{~wKDNOjtgR\"><field
name=\"END\">FIRST</field><value name=\"VALUE\"><block
type=\"variables_get\" id=\"6=$+}$AWvB)[v-ULY%0.\"><field name=\"VAR\"
id=\"n0X6;%Q,_c=4$=`tHt^@\">ignoreList</field></block></value><value
name=\"FIND\"><block type=\"variables_get\"
id=\"gPiC8%I:1C,ClMm@E+)h\"><field name=\"VAR\"
id=\"E%{F|_6VUVE]s;x=yceK\">thingId</field></block></value></block></va\
lue><value name=\"B\"><block type=\"math_number\"
id=\"/)KV?LC6;7ebjx|rMe#t\"><field
name=\"NUM\">0</field></block></value></block></value><statement
name=\"DO0\"><block type=\"text_append\"
id=\"J;;7GOyh~?h@QmS$GpfU\"><field name=\"VAR\"
id=\"Qzn]o6PxTzj]cn8bnT2k\">messageText</field><value
name=\"TEXT\"><shadow type=\"text\"><field
name=\"TEXT\"></field></shadow><block type=\"text_join\"
id=\"|4xA3YmbBj_/WySmg;b%\" inline=\"false\"><mutation
items=\"8\"></mutation><value name=\"ADD0\"><block type=\"oh_text_crlf\"
id=\"R=RwT3r2c!MldtMCh~7!\"></block></value><value name=\"ADD1\"><block
type=\"text\" id=\"qRfw,*rM9t]f]-k:QuO~\"><field
name=\"TEXT\">____________________________</field></block></value><value
name=\"ADD2\"><block type=\"oh_text_crlf\"
id=\".6xin}kznn2)oLg+PQHw\"></block></value><value name=\"ADD3\"><block
type=\"variables_get\" id=\"_~:^T3ya1r+kmE=;[!hA\"><field name=\"VAR\"
id=\"oJm$Rz.ax{=5CWVHpP6o\">thingLabel</field></block></value><value
name=\"ADD4\"><block type=\"text\" id=\",hu(4Y3uo%@~MBdyohQx\"><field
name=\"TEXT\"> (</field></block></value><value name=\"ADD5\"><block
type=\"variables_get\" id=\"G{1T=[t4mL,J]J|)WHU!\"><field name=\"VAR\"
id=\"E%{F|_6VUVE]s;x=yceK\">thingId</field></block></value><value
name=\"ADD6\"><block type=\"text\" id=\"lQ-81UfA^x01nOhBe8tV\"><field
name=\"TEXT\">): </field></block></value><value name=\"ADD7\"><block
type=\"variables_get\" id=\"-)va(!nQ2Pe@%?I3@M4V\"><field name=\"VAR\"
id=\"HrLFiEjH(SOud$zz{9iv\">thingStatus</field></block></value></block>\
</value></block></statement></block></next></block></statement><next><b\
lock type=\"controls_if\" id=\"4l=bGRXqL*m#4st3WbIV\"><value
name=\"IF0\"><block type=\"logic_negate\"
id=\";TGEaI7pk;r.Wd`XTB%m\"><value name=\"BOOL\"><block
type=\"text_isEmpty\" id=\"+|%Pzk,zFYtfTEN;/b6.\"><value
name=\"VALUE\"><shadow type=\"text\" id=\"eP+GnzQ;!+qFSR:f6Z@F\"><field
name=\"TEXT\"></field></shadow><block type=\"variables_get\"
id=\"}eT[MPm),_,qbA._-|nz\"><field name=\"VAR\"
id=\"Qzn]o6PxTzj]cn8bnT2k\">messageText</field></block></value></block>\
</value></block></value><statement name=\"DO0\"><block
type=\"telegram_with_chatID_message\" id=\"%?.)2$rZJ)1$`[CGZ9qP\"
inline=\"false\"><value name=\"MESSAGE\"><shadow type=\"text\"
id=\"%jIrNi@b+!)=WA-_P8,8\"><field name=\"TEXT\">What's
up?</field></shadow><block type=\"text_join\"
id=\"+:B^y;:|mtkaD2WvQ-/;\"><mutation items=\"2\"></mutation><value
name=\"ADD0\"><block type=\"text\" id=\"Vq%.RspM!Sb]4j|oA!Yq\"><field
name=\"TEXT\">*Things not online:*</field></block></value><value
name=\"ADD1\"><block type=\"variables_get\"
id=\";tdF%Ltj{[p+U`Yxi09~\"><field name=\"VAR\"
id=\"Qzn]o6PxTzj]cn8bnT2k\">messageText</field></block></value></block>\
</value><value name=\"BOT\"><shadow type=\"oh_thing\"
id=\"!e*,mpQ{}pF?C[R{m==`\"><field
name=\"thingUid\">telegram:telegramBot:Telegram-Bot</field></shadow></v\
alue><value name=\"CHAT_ID\"><shadow type=\"math_number\"
id=\"Atq3IW%ItA[[RXD}bR/0\"><field
name=\"NUM\">-123</field></shadow></value></block></statement></block><\
/next></block></next></block></next></block></next></block></next></blo\
ck></next></block></next></block></xml>"
type: application/javascript
script: >
var ignore, things, messageText, ignoreList, curThing, thingId,
thingLabel, thingStatus;
var logger = Java.type('org.slf4j.LoggerFactory').getLogger('org.openhab.rule.' + ctx.ruleUID);
var things2 = Java.type('org.openhab.core.model.script.actions.Things');
ignore = 'example_ID1,exampleID2';
things = ctx['things'];
messageText = '';
ignoreList = ignore.split(',');
logger.debug(ctx['things']);
for (var curThing_index in things) {
curThing = things[curThing_index];
thingLabel = curThing.getLabel()
thingId = curThing.getUID().getId()
thingStatus = curThing.getStatus()
if (ignoreList.indexOf(thingId) + 1 == 0) {
messageText += String(['\r\n','____________________________','\r\n',thingLabel,' (',thingId,'): ',thingStatus].join(''));
}
}
if (!!messageText.length) {
things2.getActions('telegram', 'telegram:telegramBot:Telegram-Bot').sendTelegram(-123, '*Things not online:*' + String(messageText));
}
type: script.ScriptAction
And the screenshot:
Thanks Rich for pointing me in the right direction.
ECMA 2021+ version of @Larsen blocky script.
configuration: {}
triggers: []
conditions: []
actions:
- inputs: {}
id: "1"
configuration:
type: application/javascript;version=ECMAScript-2021
script: >-
var ignore, things, messageText, ignoreList, curThing, thingId,
thingLabel, thingStatus;
var logger = log('Thing Status Processor');
ignore = 'ThingID1,ThingID2';
messageText = '';
ignoreList = ignore. Split(',');
logger.debug(things);
for (var curThing_index in things) {
curThing = things[curThing_index];
thingLabel = curThing.label;
thingId = curThing.UID.id;
thingStatus = curThing.status;
if (ignoreList.indexOf(thingId) + 1 == 0) {
messageText += String(['\r\n','_'.repeat("${thingLabel.length + thingId.lenght + thingStatus.length}".length),'\r\n',thingLabel,' (',thingId,'): ',thingStatus].join(''));
}
}
if (!!messageText.length) {
actions.NotificationAction.sendNotification('name@domain.com', 'Things not online: ' + String(messageText));
logger.warn('Things not online: ' + String(messageText));
}
type: script.ScriptAction
I am a little lax on the rules but please do keep in mind the rules for marketplace postings. The discussion thread should be strictly about the top post. It’s not a place to post alternative implementations unless they are suggestions to merge with the original post.
The marketplace isn’t like other sections of the forum. These are not tutorials. These are published artifacts visible from and installable from MainUI directly. The threads should remain very on topic to avoid confusion and to keep them from becoming too long to manage.
Finally, as with all of my rule templates, this one has been rewritten in ECMAScript 2021 for OH 4. See Thing Status Reporting [4.0.0.0;4.1.0.0). The capabilities of the rule have also improved.
- the rule now triggers on all Thing events instead of polling
- it passes the thing ID, old status, old detail, new status, and new detail, and the actual Thing Object to the called rule instead of a collection of all the Things that are in the given state
I would like to try the 4.0 version of the template but I don’t know how to read the passed parameters from the called script. I didn’t find anything about it…
It would have made more sense to comment on the 4.0 version of the template’s post.
How you access the passed in parameters depends on the language being used in the called script. If JS Scripting you just reference it by name. If Blockly it’s in the context block. Nashorn it’s in context
. I don’t know about Rules DSL or jRuby.
Just wondering how to list the Thing status in a custom widget with oh-repeater?
What is the SourceType used for this?
I created a similar script, but I’m stuck how to list the results
You’d have to get that information transferred to an Item. Widgets only work with Items, including oh-repeater.
The easiest thing to do would be to add a Switch Item for each Thing you care about. The rule called by this rule templarte would need to somehow maintain a mapping between the Thing and these status Items and command them ON/OFF based on the state of the Thing (Item metadata perhaps?). Then you can use Service Status Standalone Widget to display it.
This is how I do it and I add the status Switch Item to the Equipment also to make accessing the status for a device in rules easier.
I think oh-repeater can also work with JSON data so you could theoretically have just the one String Item that you post a JSON string to that the widget can parse and loop through.
Many thanks @rlkoshak - appreciated.
This is the approach I use currently, by adding/removing dummy items for Things not Online dynamically in the script.
I thought an easier way exist in OH4 in the meantime
Hello everybody,
i tried to install that, but:
2024-01-22 17:02:04.940 [ERROR] [b.automation.script.javascript.stack] - Failed to execute script:
org.graalvm.polyglot.PolyglotException: TypeError: Cannot load CommonJS module: 'openhab_rules_tools'
at com.oracle.truffle.polyglot.PolyglotMapAndFunction.apply(PolyglotMapAndFunction.java:46) ~[?:?]
at org.openhab.automation.jsscripting.internal.OpenhabGraalJSScriptEngine.lambda$13(OpenhabGraalJSScriptEngine.java:266) ~[?:?]
at java.util.Optional.orElseGet(Optional.java:364) ~[?:?]
at org.openhab.automation.jsscripting.internal.OpenhabGraalJSScriptEngine.lambda$11(OpenhabGraalJSScriptEngine.java:266) ~[?:?]
at <js>.:program(<eval>:3) ~[?:?]
at org.graalvm.polyglot.Context.eval(Context.java:399) ~[?:?]
at com.oracle.truffle.js.scriptengine.GraalJSScriptEngine.eval(GraalJSScriptEngine.java:458) ~[?:?]
at com.oracle.truffle.js.scriptengine.GraalJSScriptEngine.eval(GraalJSScriptEngine.java:426) ~[?:?]
at javax.script.AbstractScriptEngine.eval(AbstractScriptEngine.java:262) ~[java.scripting:?]
at org.openhab.automation.jsscripting.internal.scriptengine.DelegatingScriptEngineWithInvocableAndAutocloseable.eval(DelegatingScriptEngineWithInvocableAndAutocloseable.java:52) ~[?:?]
at org.openhab.automation.jsscripting.internal.scriptengine.InvocationInterceptingScriptEngineWithInvocableAndAutoCloseable.eval(InvocationInterceptingScriptEngineWithInvocableAndAutoCloseable.java:77) ~[?:?]
at org.openhab.automation.jsscripting.internal.scriptengine.DelegatingScriptEngineWithInvocableAndAutocloseable.eval(DelegatingScriptEngineWithInvocableAndAutocloseable.java:52) ~[?:?]
at org.openhab.automation.jsscripting.internal.scriptengine.InvocationInterceptingScriptEngineWithInvocableAndAutoCloseable.eval(InvocationInterceptingScriptEngineWithInvocableAndAutoCloseable.java:77) ~[?:?]
at org.openhab.core.automation.module.script.internal.handler.ScriptActionHandler.lambda$0(ScriptActionHandler.java:71) ~[?:?]
at java.util.Optional.ifPresent(Optional.java:178) [?:?]
at org.openhab.core.automation.module.script.internal.handler.ScriptActionHandler.execute(ScriptActionHandler.java:68) [bundleFile:?]
at org.openhab.core.automation.internal.RuleEngineImpl.executeActions(RuleEngineImpl.java:1187) [bundleFile:?]
at org.openhab.core.automation.internal.RuleEngineImpl.runRule(RuleEngineImpl.java:996) [bundleFile:?]
at org.openhab.core.automation.internal.TriggerHandlerCallbackImpl$TriggerData.run(TriggerHandlerCallbackImpl.java:87) [bundleFile:?]
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:539) [?:?]
at java.util.concurrent.FutureTask.run(FutureTask.java:264) [?:?]
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:304) [?:?]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136) [?:?]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635) [?:?]
at java.lang.Thread.run(Thread.java:840) [?:?]
2024-01-22 17:02:04.950 [ERROR] [internal.handler.ScriptActionHandler] - Script execution of rule with UID 'things_offline' failed: org.graalvm.polyglot.PolyglotException: TypeError: Cannot load CommonJS module: 'openhab_rules_tools'
Source Code looks as expected:
var {helpers} = require('openhab_rules_tools');
console.loggerName = 'org.openhab.automation.rules_tools.Thing Status';
// osgi.getService('org.apache.karaf.log.core.LogService').setLevel(console.loggerName, 'DEBUG');
helpers.validateLibraries('4.1.0', '2.0.1');
console.debug('ThingStatusInfoChangedEvent:' + event.toString());
var parsed = JSON.parse(event.payload);
var data = {};
data['thingID'] = event.topic.split('/')[2];
data['thing'] = things.getThing(data['thingID']);
data['oldStatus'] = parsed[1].status;
data['oldDetail'] = parsed[1].statusDetail;
data['newStatus'] = parsed[0].status;
data['newDetail'] = parsed[0].statusDetail;
rules.runRule("thingalarm-1", data, true);
Can that come from the called rule generating an error?
You are posting to the 3.x version of this rule template.
The code you posted code is the 4.x version of the rule template. See Thing Status Reporting [4.0.0.0;4.9.9.9].
If you are running OH 3, you installed the wrong version of this template. If you are seeing two versions of this rule template in the list under add-ons, make sure to choose the one with [3.2.0;3.4.9]
in the title.
If you are running OH 4, please make sure to post to that version of the template’s thread. But also make sure to look at the list of dependencies.
- OH 4.0.0 +
- JS Scripting add-on installed
- openhab-js 4.1.0 or later
- openhab_rules_tools 2.0.1 or later
openhab_rules_tools can be installed through openhabian-config or through the following command run from the $OH_CONF/automation/js folder:
npm install openhab_rules_tools
For more info see openHAB Rules Tools Announcements
Sorry for that, will check again and, if necessary, come back in the right thread.
Many thanks for pointing me in the right direction.
I wish there were a better way to manage different versions of these. For now it’s confusing. Good luck and let me know if you run into problems!