Open main menu

Platinum ground motion notifications

In order to alert listeners that an event is in progress, the datalogger implements a ground motion notification mechanism (known as gmnotify). This mechanism implements a message bus over TCP (using the standard ØMQ library from which carries notifications as messages. The JSONJavaScript Object Notation is a technique for serialising data for transmission over networks between heterogeneous systems. See Wikipedia's 'JSON' page for more details. format is used for messages, as it provides a structure that is both easy to read and simple to process.

Reference code for a test receiver is available for the development of code using these messages. The receiver is written in C using the ØMQ and Jansson libraries:


Software architecture diagram, showing messages passed in JSON between software
    modules, then combined into one JSON message and sent to the network by the
    gmnotify daemon module via ZeroMQ.

Each trigger program (level, STA/LTA, etc.) will emit a vote message when the trigger is activated. These messages are continually emitted while the trigger remains active. The voting matrix adds up all the votes it receives within a short time period, and whenever the sum of the votes crosses an activation threshold, the matrix emits a JSON message.

The JSON message describes the actual trigger. It has the initial time-stamp of the event and it contains a list of one or more votes. If more than one vote is needed to trigger the system, then the message that is sent out will record which votes are active. These messages are used internally by the trigger system actions (event file recorder etc.) and are also sent over an internal message bus to be broadcast to the world via gmnotifyd.

Alert structure

gmnotifyd is implemented with the ØMQ publish-subscribe paradigm. gmnotifyd acts as the publisher socket, and the receiver(s) are subscribers. ØMQ allows many-to-many connections, so it is possible to connect any number of publishers to any number of subscribers as required by the application. For example, a data-centre collecting data from field sites might have two subscribers (on different machines for redundancy/fail-over), and each subscriber would connect to all the publishers (field sites).

One consequence of this scheme is that a subscriber that is not connected at the moment a notification is sent out will miss that notification altogether. This is reasonable for instant alerts, where the value is in the timeliness of the data, but not reasonable for a message about a completed trigger event file, which needs to be reliable even if the station is not connected at a given instant. A different mechanism must therefore be used to discover the most recent event file.

The notifications themselves are two-part messages (ØMQ allows for multi-part messages, which are delivered as a whole, so it is not possible to receive only one part without the other parts). The first part of the message describes the reason for it, and the second part holds a JSON payload with the message's contents. At present the following types are defined, although the list may be expanded in future as need arises:

The asterisk on the end of the message name is deliberate. It allows the subscriber to select either a general message type (e.g.TRIGGER.”) or a specific set of messages (e.g.TRIGGER.1*”) without ambiguity (so in the second example it would not receive messages for “TRIGGER.10*” or “TRIGGER.11*”).

Heartbeat messages

For a TCP-based protocol to be reliable, it is necessary to implement heartbeats in the application. This detects dropped connections (e.g. due to disconnected equipment) and prevents badly-designed NAT equipment from timing out the connection.

gmnotifyd will send a heartbeat message every 30s, containing a time-stamp and the station name (host-name). The receiving application should check for these and if they stop arriving it should drop the connection and reconnect. The test receiver implements this action.

The message type will be “HEARTBEAT*”. The message content will be:

{ "hostname": "G12345", "timestamp": "2014-11-04T13:27:00Z" }

Trigger notifications

The message type will be “TRIGGER.<group>*”, where <group> is replaced with the group number configured on the EAM or NAM. If just a single group is created then this will always be 1. The message content will be:

{ "hostname": "G12345", "timestamp": "2014-11-04T13:27:13.015000000Z", "triggers": [ { /* details of vote #1 */ }, { /* details of vote #2 */ } ] }

The triggers array will contain one entry (object) for each vote that caused the trigger. It might only contain a single entry if only one vote is necessary. The contents of the trigger object have some common fields and then some type-specific fields. An example of a level trigger object:

{ "type": "level", "source": [ { "instrument": "INST-ID", "component": "N" }, { "instrument": "INST-ID", "component": "E" } ], "dimension": "acceleration", "level": 0.013479 }

Here the common fields are “type” and “source”. The trigger type-specific elements are “dimension” and “level”.

The list of trigger types will be expanded if new trigger algorithms are added to the NAM or EAM. Currently defined trigger types are:

The “source” array specifies which channel(s) the trigger is working on. In this example there are two channels, which means the trigger is operating on the vector resultant of these two channels.

Level trigger

For a level trigger, the “dimension” field specifies what the sensor is measuring (acceleration, velocity, pressure etc.). From this the units of measurement can be determined: the system always uses un-scaled SI base units (so m/s², m/s or Pa for the three examples given). This policy prevents confusion when working with institutions that use different preferred units.

The “level” field specifies the level of the first sample that exceeded the trigger. Note of course that the event could include much larger sample magnitudes than the initial trigger point.

Detailed example

This example contains two different STA/LTA triggers (running on different components of the same instrument). This example was captured from a live system, so it perfectly reflects the data being sent:

{ "timestamp": "2014-11-04T16:54:37.000000000Z", "hostname": "G20592", "triggers": [ { "type": "sta-lta", "source": [ { "instrument": "PH-5981", "component": "N" } ], "sta": "9.84941420e-04", "lta": "2.45254355e-04", "dimension": "acceleration" }, { "type": "sta-lta", "source": [ { "instrument": "PH-5981", "component": "Z" } ], "sta": "1.89603799e-02", "lta": "4.51461752e-03", "dimension": "acceleration" } ] }