Groov View REST API

I am having a little issue implementing the REST API on groov view:
So from a browser URL line I can READ a value from my groov view data store.
But when I try to write to the groov view data store, exact same variable it
fails. I am using the exact commands as specified in “Building your first groov API request” on the opto developer website.

So here is my read command (which works) and the result:
command: https://10.3.1.40/api/v1/data-store/read/2021?api_key=[my api key]
result: {“id”:2021,“valueType”:“integerValue”,“value”:0,“timestamp”:1653927841853}

Here is my write command that doesn’t work and the result:
command: https://10.3.1.40/api/v1/data-store/write/2021?value=20&api_key=[my api key]

result: This 10.3.1.40 page can’t be found
No webpage was found for the web address: https://10.3.1.40/api/v1/data-store/write/2021?value=20&api_key=[my api key]

Any ideas? My groov view is running in AR-1 box

Reads are http GET and writes are http PUT
You can do the read from the browser, but you cant do the put. (Hence the error, the page can not be found, you are trying to put a value on a ‘page’, ie write the value via REST).

Either use curl (Linux command line), Postman (browser plugin or stand alone app) or something like Node-RED or Python to do the PUT.

OK, yes I had a feeling that it was something like that. So is there a way from Snap-Pac to directly write to groov view? Without using Node Red? Seems like I saw a post one time that showed a subroutine that could write directly from a controller to another controller (that was configured for http).

Sure, you can use the SNAP PAC http commands, but I am more interested in why?
groov View can talk directly to SNAP PAC I/O and variables, there is no need to use the Data Store at all.
Can you share your use case and we can try and help out.

Yes, you’re right – I had a groov view application where I had a large number of events that were conditioned on a single bit. That was so I could disable a whole flock of alarms by just setting/resetting a single bit – and that bit ended up being within the groov data store (I should have used an integer in my controller). So it is just a convenience thing – I didn’t want to do over all of the event parameters. And I realize that I could use node red, but somehow I have an aversion to constantly polling a word on my controller, waiting for a change of state.

Gotcha. Makes sense.
Let me dig around and try to find that PAC Control sample…

I think I found it in older forum: “Peer to peer via RESTful API!” 2016. Unless you have another one too.

@TSKING1950 This is proving to be trickier than I expected… Not sure if you have anything working yet. If you do, please share, if not, I will keep working on things here.

I looked at the peer-to peer thread, them the http post command and decided to hold off for a while. I will use node red for now. Thanks for your help.

On the API docs I am looking at, they don’t show any HTTP PUT commands, only GET and POST.

Also, the POST wants the parameters in the URL. I found that strange. It seems like we should be able to post JSON or x-www-form-urlencoded values in the content. Maybe we can, but I don’t see it in the docs.

PUT would be more RESTful in this application, does it work? I didn’t bother trying since it doesn’t seem to be documented that way.

Here is what works using POST in PAC Control:

sHostName = "10.3.1.40";

sURLPath = "/api/v1/data-store/write/2021?value=20&api_key=[your api key]";

stRequestHeader[0] = "Host: " + sHostName;
stRequestHeader[1] = "User-Agent: Opto22 PAC";
stRequestHeader[2] = "Content-Length: 0";

stRequestContent[0] = "";//nothing

nPostResult = HttpPostFromStringTable(stResponseContent, stResponseHeader, stRequestContent, stRequestHeader, 1, sURLPath, nHttpStatus, 443, sHostName);

Yes, POST only. I don’t remember at the moment why I went with POST, possibly because the PAC REST API did the same?

That was mostly because it only supports writing a single value at a time, and it’s way easier to build a query string than it is a properly encoded body.

1 Like

After 45 minutes of testing, I cant get this code sample working.
Im about 5-6 hour into this so far and am unsure to keep going or give up and just advise people to use Node-RED…

The sample I posted I modified so that it would work with the groov Box api - it is slightly different for the EPIC. Here it is a bit more fleshed out with additional variables. This is working running on SoftPAC and pulling data from a PR1 data store.

//Note that the controller needs to have a trusted cert in its store for TLS.
nPort = 443;  
sHostName = "10.3.1.40";
sAPIKey = "R9igTrwJYaTSZHfk9rodd88e7ALKXnrQ";

sAPIPath = "/view/api/v1/data-store/write/"; //for EPIC
//sAPIPath = "/api/v1/data-store/write/"; //for groov box, I think
sTagId = "206";
sValue = "22";

sURLPath = sAPIPath + sTagId + "?value=" + sValue + "&api_key=" + sAPIKey;

stRequestHeader[0] = "Host: " + sHostName;
stRequestHeader[1] = "User-Agent: Opto22 PAC";
stRequestHeader[2] = "Content-Length: 0";

nPostResult = HttpPostFromStringTable(stResponseContent, stResponseHeader, stRequestContent, stRequestHeader, 1, sURLPath, nHttpStatus, nPort, sHostName);

After 2 hours of testing, I also cant get this to work.

Right now, my advice is to by all means, test @philip code, but be willing to use Node-RED.

Time to put this one to rest.

NOTE! The key is the selfsigned:0 added to the request header. With out this you get a PKI certificate error -2008. This option was added in EPIC firmware version 3.1.0 so you will need to be running this version or better for this to work.

We got it going with the help of @philip and one of the software dev’s here at Opto.
Soft PAC running on an EPIC controller talking to a groov View data store running on the same EPIC controller ie, all localhost - important for certificate reasons.

Here is the working Opto Script code:

// Code to send an int32, float or string (they are all the same) to a groov View Data Store
nPort = 443;  
sHostName = "127.0.0.1";
sAPIKey = "XxWu8aodqX9VRnnLmvUGXBrdq9TusvAN";

sAPIPath = "/view/api/v1/data-store/write/"; //for EPIC

sTagId = "2";
sValue = "88";

sURLPath = sAPIPath + sTagId + "?value=" + sValue + "&api_key=" + sAPIKey;

// The 'selfsigned:0' is important, do not remove.
stRequestHeader[0] = "Host: " + sHostName + " selfsigned:0";
stRequestHeader[1] = "User-Agent: Opto22 PAC";
stRequestHeader[2] = "Content-Length: 0";

nPostResult = HttpPostFromStringTable(stResponseContent, stResponseHeader, stRequestContent, stRequestHeader, 1, sURLPath, nHttpStatus, nPort, sHostName);