Configuring an Event for a Range of Tags

My app is configured so that when any of a range of tags reaches a certain point (in this case -2.0) it changes a gadget color and sends out an email alert. My issue is that I have to configure hundreds of these, one tag at a time. I see where I can set a range of values but where can I set a range of tags? The tags are all from a table and I can set it to an individual index but not a range of indexes. If I could do this it would save me hours of time.

Here is what I mean:

Thanks,

Dave

Not officially, no, sorry.

What I’m about to describe might not work for you, and I make no guarantee it’ll work beyond groov R3.4.

Events have their definitions built out of a chunk of JSON, and there’s a REST-ish API for listing, creating, updating, and deleting them. If you’re comfortable editing a JSON file and using Curl or Postman or something to work against a REST API, you can create an event that has two of the tags you need in it and just edit a text file (e.g. copy and paste a line a lot, changing the table index) to add the rest.

Before you try this, please back up your project in case something goes wrong. :scream:

First, you’ll need the API key from an editor user. In Build mode, look in the Configure menu and select Accounts…, and grab the API key for your user.

(Your API keys will be of the longer, ugly variety. I’m a developer, I can cheat. :innocent:)

Create your template event, and give it a name you’ll recognize. Then, using your HTTP client of choice (curl, Postman, or just open a new browser window), navigate to this URL:

https://your.groov.com/api/v0/events?api_key=your_api_key

It’ll spit out a blob of JSON at you, that unfortunately has all whitespace removed to cut down on how much bandwidth it uses. You can use something like jq or JSON Pretty Print to reformat it into something easier to work with. Look for your event name in there: there’ll be an id number right above it.

Using that id number, build up this URL that directly references your event:

https://your.groov.com/api/v0events/<id>?api_key=your_api_key

That’ll spit out the JSON for just your event. Pass it through a pretty printer, and it’ll look something like this:

{
  "id": 2,
  "name": "1 Minute Test",
  "enabled": true,
  "condition": {
    "children": [
      {
        "type": "compare",
        "comparator": ">",
        "tag_id": 2,
        "tag_index": 0,
        "tag_count": 1,
        "value": 100,
        "hysteresis": 0,
        "debounce_time": 60
      }
    ],
    "type": "or"
  },
  "sendEmailOnBegin": true,
  "sendEmailOnEnd": true,
  "beginEmail": {
    "subject": "",
    "body": ""
  },
  "endEmail": {
    "subject": "",
    "body": ""
  },
  "recipients": {
    "users": [
      1
    ],
    "groups": [],
    "everyone": false
  },
  "state": "INACTIVE",
  "errors": []
}

Copy that into a plain text editor. (Not something that allows you to change text colors or anything. Plain text only.) The part you want to focus on is this:

"children": [
  {
    "type": "compare",
    "comparator": ">",
    "tag_id": 2,
    "tag_index": 0,
    "tag_count": 1,
    "value": 100,
    "hysteresis": 0,
    "debounce_time": 60
  }
]

You’ll need one of those stanzas for each of the table indices you want to read, separated by commas. Just change the tag_index field as you paste new ones in. For example, if I wanted to scan indices 1, 2, and 3 of that tag, my children section would look like this:

"children": [
  {
    "type": "compare",
    "comparator": ">",
    "tag_id": 2,
    "tag_index": 1,
    "tag_count": 1,
    "value": 100,
    "hysteresis": 0,
    "debounce_time": 60
  },
  {
    "type": "compare",
    "comparator": ">",
    "tag_id": 2,
    "tag_index": 2,
    "tag_count": 1,
    "value": 100,
    "hysteresis": 0,
    "debounce_time": 60
  },
  {
    "type": "compare",
    "comparator": ">",
    "tag_id": 2,
    "tag_index": 3,
    "tag_count": 1,
    "value": 100,
    "hysteresis": 0,
    "debounce_time": 60
  }
]

Note that a trailing comma after the last index stanza will probably cause groov to reject it as invalid JSON.

Now! We have to get that back into groov. To do that, we need to issue an HTTP POST request to the same URL we used to retrieve the event definition in the first place, with that JSON text as the request body. I use Curl for this sort of thing, so I’d save it to a file (name it event.json or something), and then run at a command line:

curl -k --data-binary @/path/to/event.json https://my.groov.com/api/v0/events/<id>?api_key=my_api_key

If it goes well, it’ll print out the definition you just sent it. If something goes wrong, it’ll print Unable to parse event json. Assuming it worked, you should be able to pop into Build mode and check the event to make sure it’s all ok.

A few important notes:

  1. I’ll state again: don’t be surprised if you try and use this in a newer or older version of groov and it doesn’t work. This particular API will only work in groov 3.3 or 3.4. (It was under a different URL in earlier versions and didn’t support API keys.)
  2. We actually haven’t finished implementing event validation on this particular API in released versions of groov; we still use the older one that I’m not detailing here.
  3. It’s very easy if you’re not careful here to create an event that the editor can’t handle. The event execution engine’s more flexible than the editor is, and supports things like nested comparisons and whatnot.
  4. Don’t bother trying the tag_count field: it doesn’t do what it should. groov’s not built to scan tables efficiently. :frowning:
2 Likes

Hi Dave,
Are these tables in a PAC Control Strategy? If so ,I would perform this test in the controller itself. Iterating through the table and noting the indices which are out of compliance. Append these indices to a string and/or set a flag and send an email based on the flag.

Typically any bulk logic is best done in the Controller.

-Brandon McCollum

I considered that, but this particular app was written for us by somebody else and I didn’t want to modify her code if I didn’t have to. Probably will do that on future projects.

Thanks for the help.

Dave

1 Like

Thanks for the quick reply, Jonathan. Probably would take me more time to figure out how to make this work than if I just brute forced it. Having said that, it’s good to know what my options are, and this would be very useful for someone whose JSON chops are better than mine. ;-}

Dave

Hi Jonathan,

I need to do the same in R4.2a but the when I build the URL it is not returning any events. The only thing it returns is “{”.

How do I copy events in R4.2a?

Hmm, looks like there may be a bug in there. Check in your logs for a line that looks like this:

2/3/2020 11:01:07 AM	ApiServlet	An exception occurred while handling /api/v0/events

Yes, the log entry gets generated when I try to access the URL

What about a Node-RED solution? You can read the entire table in Node-RED as an array. Then use a function block to scroll through the array and set a boolean result that would be true if any of the tags are at -2. Write the boolean to a data store in the groov then use that variable to trigger the event.

Hi,

Any update on this?

Would prefer to have the events natively in View instead of processing them elsewhere and surfacing them in View.

I don’t have a date for an upcoming release to address this, no. :-/