Send multiple point value in alarm text
-
Hello, I have a question.
I want to know if it's possible to send multiple points values when an alarm is triggered? For example let's say that I have a compressor which is in alarm and when the alarm is triggered I want to send in that email values for Low Pressure, High Pressure, Discharge Temperature and Suction Temperature.
Thank you!
-
Hi @sky_watcher
It is definitely possible. You will need to make a custom template tho. Have a look at this link. https://help.infiniteautomation.com/custom-email-templates/?rq=email
You will be able to add additional points and access the names and value properties in your template. -
@craigweb Thank you for your reply, I made an example like one from the link that you suggested and I have some problems.
Below is my example:
And this is what I get in my email:
But the values that are showed there aren't for T0 and T1, are for the point that trigger the alarm.
-
Hi sky_watcher,
That is because the list you are iterating in the FTL is the
renderedHtmlPointValues
which is included in the model for the point that triggered the event. Instead, you would want to iterate over the lists you added to the model (and probably separately), so<#if pressureValues??> <#list pressureValues as index,value> ${additionalContext.pressure.deviceName} - ${additionalContext.pressure.name} - ${value.value} - ${value.time}<br/> </#list> </#if>
We have to <#list> over
index, value
because a JavaScript list is backed by a Map with the natural numbers as the keys, so it's more like looping over a map. -
@phildunlap Thank you Phil, your example works but it is a way to format the value?
For value I have to many decimals and for time it in a wired format. -
You'll have to manually get the values rendered as desired. Presumably that'll be the point's text renderer, so you could have a function like this, perhaps in a global script:
function getRenderedValues(variableName, limit) { var renderedValues = []; var textRenderer = CONTEXT_POINTS[variableName].getVO().getTextRenderer(); if(textRenderer === null || textRenderer === undefined) return renderedValues; var rawValues = p.last(10); for(var k = 0; k < rawValues.length; k+=1) { //See com.serotonin.m2m2.view.text.TextRenderer // for understanding the second argument renderedValues.push(textRenderer.getText(rawValues[k], 2)); } return renderedValues; } //Remove the print portion if a global script, or after testing print(getRenderedValues("p", 10));
-
Alternatively look into Freemarkers format options
https://freemarker.apache.org/docs/ref_builtins_date.html
https://freemarker.apache.org/docs/ref_builtins_number.html -
@phildunlap Thanks Phil, I see that the script works grate but I'm not quite sure how to transfer the result of the function to the model.put("temperatureValues", temperature.last(5));
And how can I render the time?
Thank you!
-
@jared-wiltshire I've seen your post after writing to Phil...
I'll look into the docs and come with an answer.
Thank you Jared!
-
Remove the print statement and do,
model.put("temperatureValues", getRenderedValues("temperature", 5));
-
@phildunlap I tried this before, but without removing print statement and did not worked. I tried again now after I've removed the print statement and is not working.
-
My mistake! The function probably should be doing,
function getRenderedValues(variableName, limit) { var renderedValues = []; var textRenderer = CONTEXT_POINTS[variableName].getVO().getTextRenderer(); if(textRenderer === null || textRenderer === undefined) return renderedValues; var rawValues = p.last(10); for(var k = 0; k < rawValues.length; k+=1) { //See com.serotonin.m2m2.view.text.TextRenderer // for understanding the second argument in getText renderedValues.push( {"value": textRenderer.getText(rawValues[k], 2), "time": rawValues[k].time} ); } return renderedValues; }
It was making rendered values as a list of strings, so there was not a .value or .time property for the FTL to refer to. Instead will make it a list of objects with those properties.
-
@phildunlap Still doesn't work, I don't receive any email after this modification.
-
Whoops, FTL issues,
<#if pressureValues??> <#list pressureValues as index, value> ${additionalContext.pressure.deviceName} - ${additionalContext.pressure.name} - ${value.value} - ${value.time}<br/> </#list> </#if>
There were related messages in the log file.
-
@phildunlap Yes, now work perfect for value, but the time is still in that weird format.
-
Maybe you can try
${value.time?number_to_datetime}
in the FTL or you could use a SimpleDateFormatter in the script to store it in the format you want. -
@phildunlap Yes, is working now.
Thank you a lot! Have a great day!
-
@phildunlap Hi Phil, I have to reopen this discussion, today when I played around with the email feature, I was trying to customize the email and I've noticed that the time when the alarm was triggered is not the same with the time for the values, and this make sense because I record that values in the database every minute.
So I have a question, can I print there the instant value, not a recorded value from my data base? Because when the alarm is triggered that point can have another value that the one that is last recorded in my database.
-
I think what you're looking for could be found in the Mango/ftl/ files. The eventData.ftl files shows you can do
${evt.prettyActiveTimestamp}
evt
is a https://github.com/infiniteautomation/ma-core-public/blob/main/Core/src/com/serotonin/m2m2/rt/event/EventInstance.java so you can use those getter functions in the FTL, as prettyActiveTimestamp does. -
@phildunlap Thank's, if I put this line I get the same time for all the points.
${evt.prettyActiveTimestamp}
But my question is the value in real time or is last value from my database?