Distributed Control System - Conditions

Distributed Control System - Conditions


1. Intro: Conditions Database protocols using MQ-powered services. Typical workflow: sensor is booted, then it requests initial values from Conditions database, then it starts publishing updates on Conditions. At the same time, Web UI user may request to change Conditions for a specific sensor, and receive real-time updates on changes made by sensor.

2. Participating entities: Sensor, Storage service, Web UI (+ mq broker, mysql database)
2.1 Physical deployment details:
 - Sensor = code running in the online domain (daq network), TBD
 - Storage Service = C++ daemon, storage adapter handling MySQL (+MongoDB later on). Runs at onl16.starp.bnl.gov under 'dmitry' account
 - Web UI = can be run from anywhere, given that it has access to https://dashboard1.star.bnl.gov/mqtt/ for mqtt proxy service. E.g. https://dashboard1.star.bnl.gov/dcs/ . Allows to read and update (time-series versioned, so all updates are inserts) predefined Conditions structures.
 - MQ Broker = multi-protocol broker (Apache Apollo), running at onl16.starp.bnl.gov
 - MySQL service, holding Conditions database. For now, online conditions database is used. It runs at onldb.starp.bnl.gov:3501, Conditions_fps/<bla>

3. Protocols:
 - transport protocol: MQTT (sensors, storage), WebSocket + MQTT (web ui)
 - message serialization protocol: JSON
 
4. Data Request API:
  - REGISTER, SET, GET, STORAGE, SENSOR
(see examples below the service layout image)



4.1 Example: to SET value (received by sensor and storage) :

topic: dcs/set/Conditions/fps/fps_fee
message:
  {
    dcs_id: "<client_unique_id>",
    dcs_uid: "<authenticated_login>",
    dcs_header: ["field1", "field2", ... "fieldN"],
    dcs_values: {
      <row_id1>: [ value1, value2, ... valueN ],
      ...
      <row_idN>: [ value1, value2, ... valueN ]
    }
  }

NOTE: one can set any combination of fields vs row ids, including one specific field and one specific row id.

4.2 Example: to GET values:

topic: dcs/get/Conditions/fps/fps_fee
message:
  {
    dcs_id: "<client_unique_id>",
    dcs_uid: "<authenticated_login>",
    dcs_header: ["field1", "field2" ... "fieldN"], // alternatively, ["*"] to get all available fields
    dcs_values: {
      "1": true, // <-- request row_id = 1, alternatively, do dcs_values = {} to get all avaliable rows
      "2": true,
      ...
      "N": true
    } 
  }

NOTE: one can request any combination of fields vs row ids, including one specific field and one specific row id.

4.3 Example: subscribe to response from storage:

topic: dcs/storage/Conditions/fps/fps_fee
message:
  {
    dcs_id: "<client_unique_id>",
    dcs_uid: "<authenticated_login>",
    dcs_header: ["field1", "field2", ... "fieldN"],
    dcs_values: {
      <row_id1>: [ value1, value2, ... valueN ],
      ...
      <row_idN>: [ value1, value2, ... valueN ]
    }
  }