Skip to content

Watcher Process Explanation

This document explains how the watcher process works based on the implementation in watchersOperations.js.

Overview

The watcher process is responsible for monitoring specific conditions on devices and triggering alarms when those conditions are met. It involves creating, updating, retrieving, and managing watchers and their associated alarms. The process is designed to ensure real-time monitoring and quick response to changes in device states, making it highly efficient for managing large-scale device networks.

Why It Works This Way

The watcher process is designed to:

  1. Ensure Scalability: By using database queries and in-memory processing, the system can handle a large number of devices and watchers efficiently.
  2. Enable Real-Time Monitoring: The periodic checks and hash-based comparison of device states allow for quick detection of changes.
  3. Provide Flexibility: The modular design of watcher functions (e.g., creation, retrieval, and condition evaluation) allows for easy customization and extension.
  4. Enhance Reliability: Robust error handling and validation mechanisms ensure the system remains stable even under unexpected conditions.

Key Functions

1. Creating Watchers

  • Function: createWatcher(watcherData)
  • Description: Creates a new watcher with the provided data. It ensures default values for optional fields like deviceId, sendEmail, and emails.
  • Workflow:
  • Validates and sets default values for the watcher data.
  • Inserts the watcher into the database.
  • Returns the ID of the newly created watcher.

2. Retrieving Watchers

  • Function: getAllWatchers()
  • Description: Retrieves all watchers from the database.
  • Variants:
  • getAllActiveWatchers(): Retrieves only active watchers.
  • getAllInactiveWatchers(): Retrieves only inactive watchers.
  • getWatcher(id): Retrieves a specific watcher by its ID.
  • getWatchersByDevice(id): Retrieves watchers associated with a specific device.
  • getActiveWatchersByDevice(id): Retrieves active watchers for a specific device.
  • getActiveWatchersByService(service): Retrieves active watchers for a specific service.

3. Updating Watchers

  • Function: updateWatcher(watcherData)
  • Description: Updates an existing watcher with new data.
  • Workflow:
  • Validates the provided data.
  • Updates the watcher in the database.

4. Managing Watcher Status

  • Function: changeActiveStatusWatcher(id, activate)
  • Description: Activates or deactivates a watcher based on the activate flag.

5. Handling Alarms for Watchers

  • Functions:
  • addAlarmToWatcher(id, alarmId): Associates an alarm with a watcher.
  • deleteAlarmfromWatcher(id): Removes the associated alarm from a watcher.
  • createAlarmFromWatcher(watcher, currentKeyValue, device): Creates a new alarm based on the watcher and device data.
  • deactivateAlarm(alarms, keepFirst): Deactivates alarms associated with a watcher.

6. Processing Watchers

  • Function: codecServiceCreateAlarms(newDeviceData, oldDeviceData, deviceWatchers, deviceAlarms)
  • Description: Processes device watchers and creates alarms based on the new and old device data.
  • Workflow:
  • Iterates through the list of watchers for a device.
  • Checks if conditions are triggered using checkIfValuesTriggered().
  • Handles alarms based on the triggered conditions.

7. Validating Watcher Data

  • Function: isValidWatcherData(data)
  • Description: Validates the structure and required fields of the watcher data.

8. Evaluating Conditions

  • Functions:
  • checkIfValuesTriggered(data, oldData, operations): Checks if the values in the data have triggered any conditions.
  • evaluateConditions(condition, response): Evaluates a condition or group of conditions.
  • generateCauseString(conditions): Generates a descriptive string for triggered conditions.

The watcher process is capable of searching within any JSON data provided. It includes the following capabilities:

  1. Handling Non-Existent Values:
  2. If the value being watched does not exist in the JSON, the watcher does nothing and skips further processing for that condition.

  3. Nested JSON Search:

  4. The watcher can search within nested JSON objects. To specify a nested value, the key should be formatted as a dot-separated string, e.g., "keyname.keyname.keyname".

  5. Array Handling:

  6. If the value to search is inside an array, the watcher iterates through each object in the array to find the specified key or condition.

These features make the watcher process highly flexible and capable of handling complex JSON structures efficiently.

Example of a Watcher and Its Lifecycle

Example Watcher

  • Watcher Data:
        {
          "id": "watcher123",
          "deviceId": "device456",
          "conditions": [
            { "key": "temperature", "operator": ">", "value": 75 }
          ],
          "sendEmail": true,
          "emails": ["admin@example.com"]
        }
    

Lifecycle

  1. Creation:
  2. The watcher is created using createWatcher() with the above data.
  3. It is stored in the database and assigned a unique ID.

  4. Monitoring:

  5. The watcher is retrieved using getAllActiveWatchers().
  6. The system periodically checks the device's temperature against the condition.

  7. Triggering Alarms:

  8. If the temperature exceeds 75, checkIfValuesTriggered() detects the condition.
  9. An alarm is created using createAlarmFromWatcher() and associated with the watcher.
  10. Notifications are sent via email and Webex.

  11. Deactivation:

  12. When the temperature returns to normal, deactivateAlarm() deactivates the alarm.

  13. Update or Deletion:

  14. The watcher can be updated using updateWatcher() to modify conditions or notification settings.
  15. Alternatively, it can be deleted using deleteWatcher() if no longer needed.

Notes

  • The watcher process heavily relies on database operations and JSON-based condition evaluation.
  • Proper validation and error handling are implemented to ensure robustness.