Common: The Text Message Display - read_msg and messages.txt

Cogent Tools Demo and Tutorials: Version 4.0
Prev | Chapter 12. Controller Functions | Next

# 12.5. Common: The Text Message Display - `read_msg` and `messages.txt`

The messages displayed in the Controller's right-hand text box come from a single text file (`messages.txt`, shown below). The `read_msg` function (located in `lib/common.g`) is responsible for finding the requested message and inserting it into the text box.

       /*--------------------------------------------------------------------
        * Function:    read_msg
        * Returns:     A string
        * Description: Finds a message in the messages.txt file, reads each
        *              line, and returns the whole message as a single string.
        *------------------------------------------------------------------*/
       function read_msg(msgno)
       {
         local fp, marker, msg = "", line = nil;

         fp = open("messages.txt", "r", nil);
         while(line != _eof_)
         {
           line = read_line(fp);
           marker = string("#", msgno);

The `read_msg` function opens the `messages.txt` file for reading using the Gamma `open` function. The `while` statement used with the Gamma `read_line` function lets us read the file line by line.

We find the line we need by looking for the `marker` `"#`msgno`"`, where `msgno` is the message number parameter passed to the function as a string. The `marker` is constructed using the Gamma `string` function. The Gamma `strstr` function is used for making the comparison.

           if ((strstr(line, marker)) == 0)
             {
               line = read_line(fp);
               msg = read_line(fp);
               while(line != "#END")
                 {
                   msg = string(msg, " ", line);
                   line = read_line(fp);
                 }
               line = _eof_;
             }
         }
         close(fp);
         msg;
       }

Once we get to the message, we read past one blank line, read the first line of the message, and then enter a second `while` loop. Inside this loop we use the `string` function again to join each new line of the message to the previous lines, constructing one long string. When we get to a line containing `#END`, we leave both `while` loops, use the `close` function to close the file, and return the message string (`msg`).

## The `messages.txt` file

The `messages.txt` file contains all the messages that appear in the Controller. Each message is marked by `#`number`` at the start of the title line, and `#END` at the end of the message, which are detected by the `read_msg` function. The extra line between each of these markers and the body of the message allows the text editor to reformat each message paragraph without disturbing the other lines of the file.

    #1 Controller

    \n             Welcome to the\n
           Cogent Tools Demo.\n\n   This is the Controller,
    a Gamma program that controls the other programs in the demo.  It
    automatically starts the Cascade NameServer and Cascade QueueServer
    for interprocess communication (IPC); and then it starts the Cascade
    DataHub to handle rapid data transfer.\n\n   Each program started is
    independent, communicating with the others via IPC.  You can press the
    PID Emulator button to begin.

    #END
    #1.1 Process Status Text Box

    Note: Not in use-- needs "enter" and "leave" signals for a text box.
    This is the status of every Cogent process that is currently running
    on your system.  The information is generated by the Cascade NameServer.
    \n\n   The normal view is an edited version of the Cascade NameServer
    output, created by the Controller program.  To view the unedited
    information, use the "Raw output" button.

    #END
    #2 PID Emulator

    \n               PID Emulator\n\n
    The PID Emulator is a Gamma program (emul.g) that runs behind the
    scenes, generating data to emulate a PID loop.  \n\n   Every 1/10 second
    it generates data for the variables SP (set point), MV (control
    output), and PV (process variable), and sends the data to the Cascade
    DataHub.  From there the data gets distributed to the other programs
    in the Demo.

    #END
    #3 Monitor

    \n                     Monitor\n\n   The Monitor
    is a Gamma program (monitor.g) that monitors and controls
    the PID Emulator.\n\n   From the Monitor you can adjust the PID
    Emulator, and get a visual representation of the SP, MV,
    and PV values.\n\n   All values shown and all adjustments made from the
    Monitor are exchanged with the PID Emulator via the Cascade DataHub.

    #END
    #3.1 Monitor Auto On/Off button

    \n                     Monitor\n
    \n   The 'Auto mode' button toggles the value of the Cascade
    DataHub point AUTO_001 between 0 (OFF) and 1 (ON).\n\n   The PID Emulator
    is registered for the point AUTO_001, and when its value changes to 1,
    the PID Emulator sets an "every" timer.  This changes the value of SP
    every FREQ seconds (as set by the FREQ spin button).\n\n   When the
    button clicked OFF, the value of AUTO_001 changes to 0, and the
    "every" timer gets cancelled.

    #END
    #3.1a SP slider

    \n                     Monitor\n
    \n The 'SP: Set Point' slider lets you change the set point in the
    demo.  \n\nThis slider is also activated automatically by a timer with a built-in
    delay.  You can start and stop the automatic reset by pressing the
    'Auto mode' button.  You can set the timer delay using the 'Delay'
    spin button.

    #END
    #3.2 FREQ of change spin button

    \n                     Monitor\n
    \n   The 'Delay' spin button sets the value of FREQ_001 in the
    Cascade DataHub.\n\n   The PID Emulator is registered for the point
    FREQ_001, and when that value changes, the PID Emulator resets
    frequency of the "every" timer to the new value.\n\n   The new value
    becomes the new rate of change (in seconds) of SP when the automatic
    mode is ON.

    #END
    #3.3 Kp: Proportional spin button

    \n                     Monitor\n
    \n   The 'Kp: Prop' spin button sets the proportional value PID1_Kp
    in the Cascade DataHub.  This value is a proportion applied to the
    difference (or error) between the set point (SP) and the process
    variable (PV).\n\n   The PID Emulator is registered for the point
    PID1_Kp, and when that value changes, the PID Emulator uses the new
    value.

    #END
    #3.4 Ki: Integral spin button

    \n                     Monitor\n
    \n   The 'Ki: Int' spin button sets the integral value PID1_Ki in the
    Cascade DataHub.  This value influences the rate of change of the
    control output (MV).\n\n   The PID Emulator is registered for the point
    PID1_Ki, and when that value changes, the PID Emulator uses the new
    value.

    #END
    #3.5 Kd: Derivative spin button

    \n                     Monitor\n
    \n   The 'Kd: Deriv' spin button sets the derivative value PID1_Kd in
    the Cascade DataHub.  This value inhibits rapid changes, reducing the
    amount of overshoot.\n\n   The PID Emulator is registered for the point
    PID1_Kd, and when that value changes, the PID Emulator uses the new
    value.

    #END
    #3.6 PROP: Proportional spin button

    \n                     Monitor\n
    \n   The 'PROP: Proportional' spin button controls the proportion of PV:MV
    by setting the value of PROP_001 in the Cascade DataHub.\n\n   The PID
    Emulator is registered for the point PROP_001, and when that value
    changes, the PID Emulator uses the new value.

    #END
    #3.7 INT: Integral spin button

    \n                     Monitor\n
    \n   The 'INT: Integral' spin button controls the damping effect on PV by
    setting the value of INT_001 in the Cascade DataHub.\n\n   The PID
    Emulator is registered for the point INT_001, and when that value
    changes, the PID Emulator uses the new value.

    #END
    #3.8 Good radio button

    \n                     Monitor\n
    \n   The 'Good' button resets all the MV and PV spin buttons to set
    up an optimally performing PID loop.  The new values are sent to the
    Cascade DataHub, which sends them along to the PID Emulator.\n\n   Also,
    the FREQ spin button is set to 4 to get a higher rate of change in
    automatic mode, because the PV value in a Good PID loop generally
    stabilizes in about 1 second.

    #END
    #3.9 Poor radio button

    \n                     Monitor\n
    \n   The 'Poor' button resets all the MV and PV spin buttons to set
    up a poorly performing PID loop.  The new values are sent to the
    Cascade DataHub, which sends them along to the PID Emulator.\n\n   Also,
    the FREQ spin button is set to 10 to get a low rate of change in
    automatic mode, because the PV value in a Poor PID loop might not
    stabilize for 8 or 9 seconds.

    #END
    #3.10 Oscillating radio button

    \n                     Monitor\n
    \n   The 'Oscillating' button resets all the MV and PV spin buttons to set
    up an oscillating PID loop.  The new values are sent to the Cascade
    DataHub, which sends them along to the PID Emulator.\n\n   The Automatic
    mode button is set to OFF, since automatic mode is not necessary here.

    #END
    #3.11 Out-of-control radio button

    \n                     Monitor\n
    \n   The 'Out-of-control' button resets all the MV and PV spin buttons to
    set up a PID loop with ever-increasing values.  The new values are
    sent to the Cascade DataHub, which sends them along to the PID
    Emulator.\n\n   The Automatic mode button is set to OFF, since automatic
    mode is not necessary here.

    #END
    #4 DataHub Viewer

    \n             DataHub Viewer\n\n   The
    DataHub Viewer is a Cogent utility (xdhview in GTK, phdhview in
    Photon) that gives you a window into the Cascade DataHub.\n\n   Each data
    point is listed by name, and all of its attributes, such as value,
    confidence, and the date and time the point was last updated, are
    shown.\n\n   From the DataHub Viewer you can select any point and
    manually change its attributes.

    #END
    #5 Log

    \n                      Log\n
    \n   Log is a Gamma program (log.g) that demonstrates the Cascade
    TextLogger.\n\n The Cascade TextLogger takes data from the Cascade
    DataHub and writes it in ASCII format to a file or STDOUT.  You can
    control how, when, and what data gets logged. \n\n In Linux, Log uses
    gnuplot to read the Cascade TextLogger files and generate plots of the
    data.

    #END
    #5.1 Any radio button

    \n                      Log\n
    \n   The 'Any' collect button sends a (collect any) command to the Cascade
    TextLogger, causing it to write a new line whenever a logged point's
    value changes in the Cascade DataHub.\n\n Only the new values are
    written.  Points whose values haven't changed are marked with an
    asterisk (*).\n\n This is the default setting.

    #END
    #5.2 Fill radio button

    \n                      Log\n
    \n   The 'Fill' collect button sends a (collect fill) command to the Cascade
    TextLogger, causing it to write a new line whenever a logged point's
    value changes in the Cascade DataHub.\n\n   Values for all the other
    points are filled in, even if they haven't changed.

    #END
    #5.3 All radio button

    \n                      Log\n
    \n   The 'All' collect button sends a (collect all) command to the Cascade
    TextLogger, causing it to write a new line only when all of the logged
    point's values have changed in the Cascade DataHub.\n\n   For example, in
    this demo, a line will be written right after SP changes its value,
    because all variables will have new values at that time.  The values
    for MV and PV change frequently, but no lines are written until SP's
    value changes as well.

    #END
    #5.4 Insert Text button

    \n                      Log\n
    \n   The 'Insert Text' button sends an (output) command to the Cascade
    TextLogger, causing it to write the line of text in the entry box to
    the output file.\n\n   You can send any text string you like; the "#"
    character is not necessary.  It appears in the example text because it
    marks the start of a comment for gnuplot, and when used at the
    beginning of the line it prevents creating gaps in the plots.

    #END
    #5.5 Send Cmd button

    \n                      Log\n
    \n   The 'Send Cmd' button sends a command of your choice to the Cascade
    TextLogger.  Commands are written in Lisp syntax, using parentheses.
    The (exit) command is given as an example.\n\n   Please refer to the
    Cascade TextLogger Manual for a complete list of commands and
    documentation on their use and syntax.

    #END
    #5.6 Log to: button

    \n                      Log\n
    \n   The 'Log to' button starts the Cascade TextLogger, using the
    configuration file tl.cfg, and according to the 'Collect' and 'Log to'
    options.\n\n   The file that receives the log is named tloutput.dat.
    When the 'Log to' button is unclicked, the contents of tloutput.dat
    appear in the text display.

    #END
    #5.7 file check button

    \n                      Log\n
    \n   The 'file' button sends (enable) and (disable) commands to the Cascade
    TextLogger to control logging to the tloutput.dat file.  The contents
    of this file appear in the text display when the 'Log to' button is
    unclicked.

    #END
    #5.8 stdout check button

    \n                      Log\n
    \n   The 'stdout' button sends (enable) and (disable) commands to the
    Cascade TextLogger to control logging to STDOUT.

    #END
    #5.9 Plot Recent button

    \n                      Log\n
    \n   The 'Recent' plot button calls gnuplot to create a continuously updated
    plot of the last 15 seconds of logged data.  It reads its data from
    two special data files: tlold.dat and tlrecent.dat.\n\n   NOTE: To
    simulate a trend, we run gnuplot in a loop, creating a new plot every
    second.  To close the plot window, you have to untoggle the 'Recent'
    button.  Otherwise the window will continue to be redrawn until the
    Log program exits.

    #END
    #5.10 Plot All button

    \n                      Log\n
    \n   The 'All' plot button calls gnuplot to create a continuously updated plot
    of the output.dat file.\n\n   NOTE: Because the data for this plot is
    ever-increasing, gnuplot will use progressively more system resources
    to construct a plot.\n\n   NOTE: To simulate a trend, we run gnuplot in a
    loop, creating a new plot every second.  To close the plot window, you
    have to untoggle the 'All' button.  Otherwise the window will continue
    to be redrawn until the Log program exits.

    #END
    #5.11 Demo message

    You can modify the log during run-time like this:
    \n------------Collect------------
    \nAny: logs any new data.
    \nFill: logs any new data, filling in existing data.
    \nAll: logs data only when all values have changed.
    \n
    \nInsert Text: Adds a line of text to the log.
    \n(note: the '#' is a comment character for gnuplot.)
    \n
    \nSend Cmd: Sends a command to the Cascade TextLogger.

    #END
    #6 History

    \n                      History\n
    \n   History is a Gamma program (history.g) that demonstrates the Cascade
    Historian's ability to record data and make incisive queries.

    #END
    #6.2 Record Values

    \n                      History\n
    \n   The 'Record Values' button enables the Cascade Historian to start
    recording data for MV and PV for the number of seconds indicated.
    \n\n   The data for both of these points will be collected as long
    as the PID Emulator is running.

    #END
    #6.3 Update Display

    \n                      History\n
    \n   The 'Update display' button sends a query to the Cascade Historian
    based on the current Interpolator options.\n\n   The Start
    time is the number of seconds past midnight last night, and Duration is
    the length of the query in seconds.  They are reset each time
    time the 'Record' button is used.
    \n\n   The Time Interval specifies the period for the Periodic and Fixed
    Relative interpolators.  Max. gap specifies data gap size where interpolation
    is to be suppressed.

    #END
    #6.31 NoInterpolator

    \n                      History\n
    \n   The 'NoInterpolator' option lets you run a straight query with no
    interpolation.  It plots the Y history (either MV or PV) versus
    time.

    #END
    #6.32 Periodic

    \n                      History\n
    \n   The 'Periodic' interpolator option plots the Y history (either MV
    or PV) versus time.  \n\n   It is similar to the 'NoInterpolator' option,
    except you can specify a time interval and maximum gap for the time
    axis.

    #END
    #6.33 Relative

    \n                      History\n
    \n   The 'Relative' interpolator option plots the Y history (either MV
    or PV) versus the X history (also either MV or PV).  \n\n   This
    interpolator inserts an extra value into the Y history for each value
    in the X history.

    #END
    #6.34 FixedRelative

    \n                      History\n
    \n   The 'FixedRelative' interpolator option plots the Y history (either
    MV or PV) versus the X history (also either MV or PV).
    \n\n   This interpolator inserts an extra value into the Y history for
    each value in the X history.  It is similar to the 'Relative' option,
    except you can specify a time interval and maximum gap for the time
    axis.

    #END
    #6.35 Y or X History

    \n                      History\n
    \n   The 'Y history' and 'X history' entries let you choose the variables
    for the Y-axis and X-axis (either MV or PV).

    #END
    #6.36 Start

    \n                      History\n
    \n   The 'Start' entry lets you change the start time.  This time
    is the number of seconds past midnight.  Whenever you press the
    'Record' button, the value entered here changes to the time you
    pressed the button.

    #END
    #6.37 Duration

    \n                      History\n

    \n   The 'Duration' entry lets you specify how many seconds of the
    history you wish to include in your query. Whenever you press the
    'Record' button, the value entered here changes to the number of
    seconds set in the Record spin button.

    #END
    #6.38 Time Interval

    \n                      History\n
    \n   The 'Time Interval' entry is only used in queries with a timed
    interpolator (Periodic and FixedRelative).  It sets the interval of
    time for the interpolator.

    #END
    #6.39 Max. gap

    \n                      History\n
    \n   The 'Max. gap' entry is only used in queries with the Periodic
    interpolator.  If the time between two data points exceeds this number
    of seconds, then data will not be interpolated between those points.
    This is useful if you have large gaps in your data set.

    #END
    #6.4 Plot Data

    \n                      History\n
    \n   The 'Plot Data' button calls gnuplot to create a plot of the last
    query.  Whenever you make a new query, the plot is automatically
    updated.\n\n   NOTE: To support the automatic update feature, we run
    gnuplot in a loop, creating a new plot every second.  To close the
    plot window, you have to untoggle the Plot Data' button.  Otherwise
    the window will continue to be redrawn until the History program
    exits.

    #END
    #6.5 Deadband Types button

    \n                      History\n
    \n   The 'Set up deadband types' button opens the Deadband Types window,
    where you can set the type of deadband on data collected for MV or PV.

    #END
    #6.51 Deadband: Full data set

    \n                      History\n
    \n   The 'Full data set' option shows the history that was recorded with
    no deadband.

    #END
    #6.52 Deadband on, prior off

    \n                      History\n

    \n   The 'Deadband on, prior value off' shows the history that was
    recorded with a standard deadband.

    #END
    #6.53 Deadband on, prior on

    \n                      History\n
    \n   The 'Deadband on, prior value on' shows the history that was
    recorded with the deadband on, adding for each point displayed the
    value that was recorded immediately before.  This can give a more
    accurate picture of the data set in certain circumstances.

    #END
    #6.54 Deadband Types Window

    \n                      History\n
    \n   The Deadband Types window lets you set the type of deadband on data
    collected for MV or PV, to filter out redundant data.\n\n   You can
    deadband the data itself on an absolute or percent basis, or both.  And
    you can set time limits or count limits for when data gets collected.

    #END
    #6.55 Cancel

    \n                      History\n
    \n   The 'Cancel' button reverts the values in the Deadband window back
    to what they were the last time the 'OK' button was clicked, and closes
    the window.

    #END
    #6.56 OK

    \n                      History\n
    \n   The 'OK' button sends the query to the Cascade Historian and closes
    the Deadband window.  The values last entered in the window are the ones
    sent.

    #END

Prev | Home | Next
Photon: the Controller window - `create_control_win` | Up | Common: The Process Status Display - `show_names`, `toggle_raw`, `.reassign_prog_name`, `extra_space`

Copyright 1995-2002 by Cogent Real-Time Systems, Inc.