I was wondering if it is possible to utilize ArcGIS Velocity to detect an attribute change/edit, to trigger another action, like sending a text message or email? Has anybody done this?
Solved! Go to Solution.
@ArmstKP yes it is possible to detect a attribute change in real time. One way to do this is to use Track functions - TrackFieldWindow
https://developers.arcgis.com/arcade/function-reference/track_functions/#trackfieldwindow
Track Functions can be use in the Calculate Field and Map Field tool arcade expressions:
Here is a sample workflow using a simple AVL feed tracking snow plows with a driver name attribute that could change as time passes.
Using DriverName and the TrackFieldWindow to send a notification when the change is detected.
TrackFieldWindow ( fieldName , startIndex , endIndex )
fieldName = driverName accessed as 'driverName'
startIndex = Past Feature (-1) accessed using TrackFieldWindow(-1,0)[0]
endIndex = Current Feature (0) accessed using $feature.driverName
// Get the prior observation value for the field using TrackFieldWindow
var priorValueArray = TrackFieldWindow('driverName', -1, 0)[0];
// Get the current feature observation value for the currentValue field
var currentValue = $feature.driverName;
// Handle the case where the first value does not have a prior feature
// If there is a prior value, determine if the value changed
if(count(priorValueArray) < 1){
return false;
} else {
return IIf(priorValueArray[0] != currentValue, true, false);
}
Then if the past feature and current feature are the same it returns - False
If past feature and current feature are different is returns - True indicating a attribute change.
Once you have that set you can leverage the filter tool to detect that change the send out a notification.
This is just one example but this workflow can be modified to reflect other use cases
@ArmstKP yes it is possible to detect a attribute change in real time. One way to do this is to use Track functions - TrackFieldWindow
https://developers.arcgis.com/arcade/function-reference/track_functions/#trackfieldwindow
Track Functions can be use in the Calculate Field and Map Field tool arcade expressions:
Here is a sample workflow using a simple AVL feed tracking snow plows with a driver name attribute that could change as time passes.
Using DriverName and the TrackFieldWindow to send a notification when the change is detected.
TrackFieldWindow ( fieldName , startIndex , endIndex )
fieldName = driverName accessed as 'driverName'
startIndex = Past Feature (-1) accessed using TrackFieldWindow(-1,0)[0]
endIndex = Current Feature (0) accessed using $feature.driverName
// Get the prior observation value for the field using TrackFieldWindow
var priorValueArray = TrackFieldWindow('driverName', -1, 0)[0];
// Get the current feature observation value for the currentValue field
var currentValue = $feature.driverName;
// Handle the case where the first value does not have a prior feature
// If there is a prior value, determine if the value changed
if(count(priorValueArray) < 1){
return false;
} else {
return IIf(priorValueArray[0] != currentValue, true, false);
}
Then if the past feature and current feature are the same it returns - False
If past feature and current feature are different is returns - True indicating a attribute change.
Once you have that set you can leverage the filter tool to detect that change the send out a notification.
This is just one example but this workflow can be modified to reflect other use cases
@JeffEismanGIS This is great! Thank you for such detailed step by step instructions as well! Much appreciated.
I copied the expression that you wrote and added my field name in. I get this error, though. Any idea?
@JeffEismanGIS Can you tell me why I might be getting the above error of "Out of Bounds"?
I have seen that error before. Is your feed running? If not start in and try it again. If it is running can you send me a sample of your data to look at. I think you have the option to message me directly.
@ArmstKP In looking a bit more into your problem there is one frontend limitation in array access of prior features, but we have a simple workaround that I could assist with on a call and screenshare. This will be fixed in our late Feb release.
@ArmstKP I wonder if it is because index -1 does not exist for the very first observation for a track, when the feed is started; and might not exist when the Velocity UI is evaluating the expression. Perhaps you could try adding "if (TrackIndex() > 0)" to the Arcade expression and only invoke TrackFieldIndex when that is true? (Just a hunch; honestly I have not tried using any of the Track functions in a Real Time Analytic and didn't even realize they would work there. Thanks @JeffEismanGIS for pointing that out!)
@brudo @JeffEismanGIS Brudo, that is an interesting observation, I will have to look into it. I did make a change to the expression that Jeff posted above. I removed the '[0]' and the expression tested successfully...
@ArmstKP @brudo At the 3.3 Velocity release (current) the Arcade expression evaluation code is not capable of evaluating negative index values for Track functions. This shortcoming has already been fixed for our 4.1 release that will go live in production late February.
The workaround is to build your expression with positive values such as [1,2], and then to use the Velocity API to modify the value set in the analytic configuration for that expression. For assistance with that process please either create an Esri Support case or reach out to myself or @JeffEismanGIS directly via Esri community direct message to exchange contact information and schedule a call. As soon as our next release goes live in February, this extra step will no longer be required.
As an update to this, see @JeffEismanGIS 's edited comment above and @brudo 's suggestion
We can use an "if" function determination to assess the array length an if less than 1, we can return a false boolean type and not require any API level modifications prior to the Feb 2023 Velocity update.
// Get the prior observation value for the field using TrackFieldWindow
var priorValueArray = TrackFieldWindow('driverName', -1, 0)[0];
// Get the current feature observation value for the currentValue field
var currentValue = $feature.driverName;
// Handle the case where the first value does not have a prior feature
// If there is a prior value, determine if the value changed
if(count(priorValueArray) < 1){
return false;
} else {
return IIf(priorValueArray[0] != currentValue, true, false);
}