Email Event Handler - support for multistate and binary values
-
MangoGT 3.7.7
How to make an Event Handler to email rendered multistate values and binary points please?
At the moment multistate data point returns raw value and binary blocks emails from sending altogether (errors in .ma file)..ma file :
ERROR 2021-05-04T09:27:34,289 (com.serotonin.m2m2.rt.event.handlers.EmailHandlerRT.sendEmail:468) - Error sending email java.lang.NullPointerException: null at com.serotonin.m2m2.rt.event.handlers.EmailHandlerRT.sendEmail(EmailHandlerRT.java:292) ~[mango-3.7.7.jar:?] at com.serotonin.m2m2.rt.event.handlers.EmailHandlerRT.sendEmail(EmailHandlerRT.java:208) ~[mango-3.7.7.jar:?] at com.serotonin.m2m2.rt.event.handlers.EmailHandlerRT.scheduleTimeout(EmailHandlerRT.java:165) ~[mango-3.7.7.jar:?] at com.serotonin.m2m2.rt.event.handlers.EmailHandlerRT.scheduleTimeout(EmailHandlerRT.java:79) ~[mango-3.7.7.jar:?] at com.serotonin.m2m2.util.timeout.ModelTimeoutTask.run(ModelTimeoutTask.java:36) ~[mango-3.7.7.jar:?] at com.serotonin.timer.Task.runTask(Task.java:179) ~[mango-3.7.7.jar:?] at com.serotonin.timer.TaskWrapper.run(TaskWrapper.java:23) ~[mango-3.7.7.jar:?] at com.serotonin.timer.OrderedThreadPoolExecutor$OrderedTaskCollection.run(OrderedThreadPoolExecutor.java:314) ~[mango-3.7.7.jar:?] at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128) ~[?:?] at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628) ~[?:?] at java.lang.Thread.run(Thread.java:830) [?:?]
-
In order to help you a little more here without confusing you in the process... Can you explain what you want to trigger the event and thus send the email?
You can send an alert based upon value thresholds being crossed or no change in value or no updates for a period of time.
If however you mean how you render the data, perhaps looking at writing a .ftl file will be a better port of call. Can show you how to assemble a model and map all affiliated values as desifed withba script...
After that happy to walk you through the process.
Fox
-
thanks Matt.
more context...
We've got event handlers, and they are working fine.But now we need to enhance the emails to show a bit more data at the time of the event, thus populate some data points values into the email e.g.
State (multistate type data point with 15 rendered values e.g. 1=Ready, 2=Fault etc) or
Alarm (binary type, 0=Inactive, 1=Active).I'm defining these data points in Event Handler Script:
model.put("p1",p1.value) model.put("p2",p2.value)
and adding code into Custom Email Template:
<table> <tr> <th>State</th> <td>${p1}</td> </tr> <tr> <th>Alarm</th> <td>${p2}</td> </tr> </table>
result as per initial post:
when only multistate data point defined in the code above, I'm getting an email and it contains State value as '1', not as I would expect - 'Ready'
and when binary data point is in the code - email is not getting send
-
Look at this code for a script which fires an email using the email handler directly:
https://forum.mango-os.com/topic/3147/email-last-day-s-events/2You should either use freemarker markup ie
<#if value == 1>Alt</#if>
or append to your freemarker object the renderedValue for each item as you iterate through them at the given time.model.put("p1",p1.value)
model.put("p2",p2.value)
However, looking at above, you're 'putting'
p1.value
, notp1.renderedValue
EDIT: that might actually be.rendered
not renderedValue!
Try that first and if no luck then perhaps building on a script that gives a better defined message using pointLocator data inside the datapoint itself for multistate values.Fox
-
Both 'renderedValue' and 'rendered' return 'undefined' in email unfortunately.
Would you be able to help with the script please?
-
Here is something I have written for you to pull the rendered text values for binary and multistate points.
Now you can use the created object to "map" your current values to their rendered text equivalents...
If you don't understand how this works, feel free to yell out.var rql="or("; var items=[] //Get all points attached to the script context for(var i in CONTEXT_POINTS) { items.push('eq(xid,'+this[ i].getDataPointWrapper().xid+')'); } //Build RQL query rql+=items.join(',') + ')'; //get configs of all of these points var dataPoints=JSON.parse(JsonEmport.dataPointQuery(rql)).dataPoints; var ptMap={}; //Iterate through to get the rendered values for(var i=0;i<dataPoints.length;i++) { ptMap[ dataPoints[ i ].xid ] = {}; if(dataPoints[i ].textRenderer.type==="BINARY") { //Set Binary renderedValues ptMap[ dataPoints[ i].xid ][0] = dataPoints[ i].textRenderer.zeroLabel; ptMap[ dataPoints[i ].xid ][1] = dataPoints[i ].textRenderer.oneLabel; } else if(dataPoints[i ].textRenderer.type==="MULTISTATE") { //Or get the multistate values for(var j=0;j<dataPoints[i ].textRenderer.multistateValues.length;j++) { ptMap[ dataPoints[i ].xid ][dataPoints[ i].textRenderer.multistateValues[j].key] = dataPoints[ i].textRenderer.multistateValues[j].text; } } } //Print here just to show format of mapping. Can comment out. print(JSON.stringify(ptMap) ); //so ptMap[xid][ ptValue ] => renderedValue
Fox