[link="http://www.everdyn.com/blog/"]From Everdyn's blog[/link]
I want to talk today about the AlarmClient control used in ArchestrA Graphics. It is similar to the InTouch Alarm Viewer ActiveX control and I suspect is largely a .Net wrapper of that control.
We have built an alarm page with a number of filters on it that can be opened from many different locations. Defending on where it is opened it must filter for different alarms. Alarms can come from 1 of 4 servers. They are non-redundant, high availability VMs (hosted on redundant hardware). One or more servers can be shut down for operational reasons.
Consider the following logical (model view) structure:
Image may be NSFW.
Clik here to view.
Assume Fab1 and all its objects are hosted on one server, and Fab2 on a second. Where should Plant be deployed? Neither server is acceptable as either could be shut down for operational reasons. Lets assume we put it on the GR. The alarm query would look like this.
Image may be NSFW.
Clik here to view.
This will return all alarms in the system. However there is a problem. Lets say there are 1000 alarms in Fab1 and 1000 in Fab2. All 2000 need to be forwarded to the GR that will then forward them to alarm clients. This is effectively double the necessary traffic of the following query.
\\FAB1-Server\Galaxy!Fab1 \\FAB2-Server\Galaxy!Fab2
Here there are actually 2 queries, but the network traffic is lower. Data also updates faster as the alarm client gets its data direct from the 2 servers.
Alarm Query Format
The format from ArchestrA IDE Help is
\\Node\Provider!Area!Filter
Lets break this down:
Node – fairly obviously the computer to query. This is the PC name, not the platform name
Provider. This is ‘Galaxy’ – which means the ArchestrA platform object will serve the alarms. Note the platform must have “Enable InTouch alarm provider” checked. The provider serves the alarms, but does not actually generate them. It just acts as an interface between ArchestrA and Intouch
Area. Area objects aggregate alarms. You can query any area object and it will provide all the alarms from all the objects in it and also from any areas it contains.
Filter. This is a very simply filter that supports the wildcard * at either the beginning or end but not both. I don’t bother with it. I subscribe to the area to get all the alarms from that area and let the alarm control filter what gets displayed vie the query filter
Query Filter Format
Filters can be built at design time or runtime using the filter builderImage may be NSFW.
Clik here to view.
However it is often necessary to make up the filter dynamically at run time. In this case you need to know the format. They take the form of a SQL where clause. In the example above the filter is
(Provider = 'Galaxy' AND state = 'UNACK')
The ‘Provider’ clause in mandatory for current alarms (this client will also retrieve historical alarms from a database). If you remove it the following message is displayed.
Image may be NSFW.
Clik here to view.
It is possible to ignore what it says about the group. If the query is written well it should not be necessary to filter for groups as only the groups of interest are queried. If it complains you can use a dummy group. I have in the past used the clause:
Group = ‘IDontCare’
There is however a good reason to set all the fields in the query – depending on how your code operates.
Interaction between Query and Filter
The AlarmClient control attempts to figure out what the query should be from your filter. Changing the filter causes the query to be re-built. This can be very annoying if you are trying to build a dynamic screen.
For example if I add a new query at run-time (you can’t edit the default query) so that the filter is
(Provider = 'Galaxy' AND state = 'UNACK')
and I check the query (right click on the alarm control and select ‘Statistics…’) the following appears
Image may be NSFW.
Clik here to view.
The query has been destroyed. The nodename is gone and the areas are gone – so although they are not needed for filtering, the filter wants to know them. This is what happen when the query is edited using the runtime user interface.
If however you interact with the control using script it works backwards. The script can write to either the query or the filter. Writing to the filter does not effect the query, but writing to the query does overwrite the filter – the reverse of when edit the filter with the run-time interface.
It seems best to choose one method. The run-time user interface gives the user a lot of freedom, but he needs to know what he is doing. I prefer to lock down those controls and give the user a few radio buttons to adjust the query.
What I have found works is to adjust the Query first. This will then overwrite the filter. A short time (100ms) later re-apply the simplified query. As the filter is not going to be used to rebuild the query, it does not need to contain nodename and area. It only needs to contain addition filters like specific tagnames or states (UNACK / ACK etc)
Oh – how do you write to the query and filter grammatically?
The query to written to the ‘AlarmQuery’ property. The Filter is a little harder to find. It is the property ‘QueryFilters.DefaultFilter.FilterCriteria’.
Good luck!
The post ArchestrA Alarm Client – Explaining Alarm Query and Query Filter appeared first on EVERDYN.