Up until now we've dealt with the PI Web API strictly as a request and response type
format. What if you want your application to know when the values for a particular
tag have changed and automatically respond rather than requiring a request to identify
changed values. The PI Web API has channels which support WebSockets to do just that.
WebSockets function on a different protocol from HTTP requests called WSS or secure
WebSockets simulator to how HTTP is secured by SSL Certificates. A WebSocket will open
up a persistent connection to the PI Web API service. The channel will remain open
to receive any payloads from the PI Web API service. The channel is registered
for particular points or attributes and when a new or changed data value arrives the new value
will automatically be sent to the channel. We only need to pick up these events ourselves and
process them. The JSON messages containing all of the stream value changes will be in the same
format as the get end endpoint for streams and stream set controllers. Channels have a polling
interval which determines how often the PI Web API sends these updates through the channel. This
can be changed by the channel polling interval configuration attribute in the AF configuration
database which sets the number of milliseconds between polls. The default is once every second.
If there are any updates in between polls from the PI Web API say for example you have
a tag which updates every quarter second and a polling interval is one second,
these events will be sent too. As a result you can have a multiple event updates for a single
message in the channel. It's also important to note that in the case of multiple event
updates for a single message the updates are not guaranteed to be in chronological order
in the JSON response message being returned by the channel. In order to use channels we
first need to open a web socket with the PI Web API. This initial opening of a web socket is an
HTTP request and can support URL parameters such as include initial values to get a value
upon opening the WebSocket. The request for the WebSocket to be opened is the base URL / streams
/ the web ID of the streams and then channel. For this example I'll be using a tag I created in an
earlier video as I plan on writing values to it to demonstrate the features of the WebSocket.
To demonstrate WebSockets we're going to need to add a new tool to our toolset an online WebSocket
tester. We're going to open up a web socket in the tester then post new values to the point
we've opened the web socket for and see the values have updated in the tester. Let's use
web socket dot org slash echo. For this I've made a few changes to my security temporarily to expose
my PI Web API service to allow connections from outside my testing domain. In the location we'll
put the URL for the test tag. Note the change from HTTPS to WSS, streams the web ID of our tag,
followed by Channel. Let's connect. Now that we can see everything is connected
up let's use fiddler to send some new values. I have a pre-written post for this tag here.
I'll hit execute we see the 202 result for the post means that the value is accepted,
so let's check on our web socket to confirm that that value was able to be received by the channel.
As you can see the new values are updating in
our testing tool. Let's take a look at this in a little bit more clean format.
I'm using this JSON formater website to make the JSON look a little bit cleaner. We see the web ID,
the name of my tag, the path to the tag as well as the new event that we've added to this stream.
Now that we've seen that the websocket can receive new values let's test out deleted values or edited
values. Let's open up system management tools and edit an event for this tag and save it .
Again we can see that change being reflected in our client though this
time the update is formatted a bit differently. As you can see
the substituted flag is now true. Now let's delete an event with system management tool.
Now this time we can see the value is no data or system digital state. When developing your
application if you elect to use WebSockets remember to handle all of these multiple
types of events in case events were deleted or values were edited or backfilled in order
to take advantage of WebSockets you'll need to have an observable or similar in your client
code that's capable of handling programmatic events when new messages are received in the
WebSocket. If you're concerned about the WebSocket channel being broken and your
client application not being informed of that network interruption you can
use the heartbeat to confirm the WebSocket is still alive and connected to the PI Web API.
To add a heartbeat to the channel you'll need to add the heartbeat rate URL parameter
on the initial opening of the WebSocket. So let's disconnect this and demonstrate that.
We can see that we get a number of null update events now so if you're planning
on using the heartbeat to confirm that your WebSocket is still alive,
remember that you will need to handle null updates. If you ever need to know how many
channels you have open you can always query through the channels / instances endpoint
on the PI Web API. This keeps a running list of channel instances. As we can see
we have one channel currently open and we've had 39 messages sent to that channel so far.
In this video we introduced channels, a tool that allows you to react updates for points
as they occur. We also discussed how the underlying technology for channels are web
sockets. We demonstrated web sockets by using web socket dot org online test client to post
new values. We demonstrated the difference in message format when the values are updated,
as well as the difference in message format when values are deleted. And lastly we introduced
some health checks for channels such as the heartbeat rate URL parameter which provides
null updates in the case when no updates are available for the stream. We also showcased
the channel slash instances endpoint for keeping track of your currently open channels.
We hope you find use in the channels feature of the PI Web API.