Index: trunk/webapps/dynamicdata/cms_messages.json
===================================================================
--- trunk/webapps/dynamicdata/cms_messages.json	(revision 430)
+++ trunk/webapps/dynamicdata/cms_messages.json	(revision 431)
@@ -1,47 +1,3 @@
 {"data":[
-{"cms":{"index":"74","message":{"displayTime":"","phase1":{"Line1":"","Line2":"","Line3":""},"phase2":{"Line1":"","Line2":"","Line3":""}}}},
-{"cms":{"index":"31","message":{"displayTime":"","phase1":{"Line1":"","Line2":"","Line3":""},"phase2":{"Line1":"","Line2":"","Line3":""}}}},
-{"cms":{"index":"95","message":{"displayTime":"","phase1":{"Line1":"","Line2":"","Line3":""},"phase2":{"Line1":"","Line2":"","Line3":""}}}},
-{"cms":{"index":"93","message":{"displayTime":"","phase1":{"Line1":"","Line2":"","Line3":""},"phase2":{"Line1":"","Line2":"","Line3":""}}}},
-{"cms":{"index":"57","message":{"displayTime":"","phase1":{"Line1":"","Line2":"","Line3":""},"phase2":{"Line1":"","Line2":"","Line3":""}}}},
-{"cms":{"index":"91","message":{"displayTime":"","phase1":{"Line1":"","Line2":"","Line3":""},"phase2":{"Line1":"","Line2":"","Line3":""}}}},
-{"cms":{"index":"53","message":{"displayTime":"","phase1":{"Line1":"","Line2":"","Line3":""},"phase2":{"Line1":"","Line2":"","Line3":""}}}},
-{"cms":{"index":"73","message":{"displayTime":"","phase1":{"Line1":"","Line2":"","Line3":""},"phase2":{"Line1":"","Line2":"","Line3":""}}}},
-{"cms":{"index":"75","message":{"displayTime":"","phase1":{"Line1":"","Line2":"","Line3":""},"phase2":{"Line1":"","Line2":"","Line3":""}}}},
-{"cms":{"index":"92","message":{"displayTime":"","phase1":{"Line1":"","Line2":"","Line3":""},"phase2":{"Line1":"","Line2":"","Line3":""}}}},
-{"cms":{"index":"44","message":{"displayTime":"","phase1":{"Line1":"","Line2":"","Line3":""},"phase2":{"Line1":"","Line2":"","Line3":""}}}},
-{"cms":{"index":"90","message":{"displayTime":"","phase1":{"Line1":"","Line2":"","Line3":""},"phase2":{"Line1":"","Line2":"","Line3":""}}}},
-{"cms":{"index":"54","message":{"displayTime":"","phase1":{"Line1":"","Line2":"","Line3":""},"phase2":{"Line1":"","Line2":"","Line3":""}}}},
-{"cms":{"index":"98","message":{"displayTime":"","phase1":{"Line1":"","Line2":"","Line3":""},"phase2":{"Line1":"","Line2":"","Line3":""}}}},
-{"cms":{"index":"77","message":{"displayTime":"","phase1":{"Line1":"","Line2":"","Line3":""},"phase2":{"Line1":"","Line2":"","Line3":""}}}},
-{"cms":{"index":"94","message":{"displayTime":"","phase1":{"Line1":"","Line2":"","Line3":""},"phase2":{"Line1":"","Line2":"","Line3":""}}}},
-{"cms":{"index":"40","message":{"displayTime":"","phase1":{"Line1":"","Line2":"","Line3":""},"phase2":{"Line1":"","Line2":"","Line3":""}}}},
-{"cms":{"index":"70","message":{"displayTime":"","phase1":{"Line1":"","Line2":"","Line3":""},"phase2":{"Line1":"","Line2":"","Line3":""}}}},
-{"cms":{"index":"72","message":{"displayTime":"","phase1":{"Line1":"","Line2":"","Line3":""},"phase2":{"Line1":"","Line2":"","Line3":""}}}},
-{"cms":{"index":"65","message":{"displayTime":"","phase1":{"Line1":"","Line2":"","Line3":""},"phase2":{"Line1":"","Line2":"","Line3":""}}}},
-{"cms":{"index":"97","message":{"displayTime":"","phase1":{"Line1":"","Line2":"","Line3":""},"phase2":{"Line1":"","Line2":"","Line3":""}}}},
-{"cms":{"index":"66","message":{"displayTime":"","phase1":{"Line1":"","Line2":"","Line3":""},"phase2":{"Line1":"","Line2":"","Line3":""}}}},
-{"cms":{"index":"79","message":{"displayTime":"","phase1":{"Line1":"","Line2":"","Line3":""},"phase2":{"Line1":"","Line2":"","Line3":""}}}},
-{"cms":{"index":"78","message":{"displayTime":"","phase1":{"Line1":"","Line2":"","Line3":""},"phase2":{"Line1":"","Line2":"","Line3":""}}}},
-{"cms":{"index":"99","message":{"displayTime":"","phase1":{"Line1":"","Line2":"","Line3":""},"phase2":{"Line1":"","Line2":"","Line3":""}}}},
-{"cms":{"index":"80","message":{"displayTime":"","phase1":{"Line1":"","Line2":"","Line3":""},"phase2":{"Line1":"","Line2":"","Line3":""}}}},
-{"cms":{"index":"81","message":{"displayTime":"","phase1":{"Line1":"","Line2":"","Line3":""},"phase2":{"Line1":"","Line2":"","Line3":""}}}},
-{"cms":{"index":"55","message":{"displayTime":"","phase1":{"Line1":"","Line2":"","Line3":""},"phase2":{"Line1":"","Line2":"","Line3":""}}}},
-{"cms":{"index":"82","message":{"displayTime":"","phase1":{"Line1":"","Line2":"","Line3":""},"phase2":{"Line1":"","Line2":"","Line3":""}}}},
-{"cms":{"index":"37","message":{"displayTime":"","phase1":{"Line1":"","Line2":"","Line3":""},"phase2":{"Line1":"","Line2":"","Line3":""}}}},
-{"cms":{"index":"87","message":{"displayTime":"","phase1":{"Line1":"","Line2":"","Line3":""},"phase2":{"Line1":"","Line2":"","Line3":""}}}},
-{"cms":{"index":"71","message":{"displayTime":"","phase1":{"Line1":"SLOW FOR THE","Line2":"","Line3":"CONE ZONE"},"phase2":{"Line1":"","Line2":"","Line3":""}}}},
-{"cms":{"index":"76","message":{"displayTime":"","phase1":{"Line1":"","Line2":"","Line3":""},"phase2":{"Line1":"","Line2":"","Line3":""}}}},
-{"cms":{"index":"86","message":{"displayTime":"","phase1":{"Line1":"SLOW TRAFFIC","Line2":"AHEAD","Line3":"USE CAUTION"},"phase2":{"Line1":"","Line2":"","Line3":""}}}},
-{"cms":{"index":"83","message":{"displayTime":"","phase1":{"Line1":"","Line2":"","Line3":""},"phase2":{"Line1":"","Line2":"","Line3":""}}}},
-{"cms":{"index":"51","message":{"displayTime":"","phase1":{"Line1":"","Line2":"","Line3":""},"phase2":{"Line1":"","Line2":"","Line3":""}}}},
-{"cms":{"index":"63","message":{"displayTime":"","phase1":{"Line1":"","Line2":"","Line3":""},"phase2":{"Line1":"","Line2":"","Line3":""}}}},
-{"cms":{"index":"88","message":{"displayTime":"","phase1":{"Line1":"","Line2":"","Line3":""},"phase2":{"Line1":"","Line2":"","Line3":""}}}},
-{"cms":{"index":"89","message":{"displayTime":"","phase1":{"Line1":"","Line2":"","Line3":""},"phase2":{"Line1":"","Line2":"","Line3":""}}}},
-{"cms":{"index":"84","message":{"displayTime":"","phase1":{"Line1":"","Line2":"","Line3":""},"phase2":{"Line1":"","Line2":"","Line3":""}}}},
-{"cms":{"index":"85","message":{"displayTime":"","phase1":{"Line1":"","Line2":"","Line3":""},"phase2":{"Line1":"","Line2":"","Line3":""}}}},
-{"cms":{"index":"30","message":{"displayTime":"","phase1":{"Line1":"","Line2":"","Line3":""},"phase2":{"Line1":"","Line2":"","Line3":""}}}},
-{"cms":{"index":"96","message":{"displayTime":"","phase1":{"Line1":"","Line2":"","Line3":""},"phase2":{"Line1":"","Line2":"","Line3":""}}}},
-{"cms":{"index":"69","message":{"displayTime":"","phase1":{"Line1":"","Line2":"","Line3":""},"phase2":{"Line1":"","Line2":"","Line3":""}}}},
 {"cms":{"index":"10","message":{"displayTime":"","phase1":{"Line1":"","Line2":"","Line3":""},"phase2":{"Line1":"","Line2":"","Line3":""}}}},
 {"cms":{"index":"11","message":{"displayTime":"","phase1":{"Line1":"","Line2":"","Line3":""},"phase2":{"Line1":"","Line2":"","Line3":""}}}},
@@ -50,4 +6,5 @@
 {"cms":{"index":"14","message":{"displayTime":"","phase1":{"Line1":"","Line2":"","Line3":""},"phase2":{"Line1":"","Line2":"","Line3":""}}}},
 {"cms":{"index":"15","message":{"displayTime":"","phase1":{"Line1":"","Line2":"","Line3":""},"phase2":{"Line1":"","Line2":"","Line3":""}}}},
+{"cms":{"index":"16","message":{"displayTime":"","phase1":{"Line1":"","Line2":"","Line3":""},"phase2":{"Line1":"","Line2":"","Line3":""}}}},
 {"cms":{"index":"17","message":{"displayTime":"","phase1":{"Line1":"","Line2":"","Line3":""},"phase2":{"Line1":"","Line2":"","Line3":""}}}},
 {"cms":{"index":"18","message":{"displayTime":"","phase1":{"Line1":"","Line2":"","Line3":""},"phase2":{"Line1":"","Line2":"","Line3":""}}}},
@@ -56,10 +13,53 @@
 {"cms":{"index":"21","message":{"displayTime":"","phase1":{"Line1":"","Line2":"","Line3":""},"phase2":{"Line1":"","Line2":"","Line3":""}}}},
 {"cms":{"index":"23","message":{"displayTime":"","phase1":{"Line1":"AMAZINGLY FEW","Line2":"DISCOS","Line3":""},"phase2":{"Line1":"","Line2":"","Line3":""}}}},
-{"cms":{"index":"16","message":{"displayTime":"","phase1":{"Line1":"","Line2":"","Line3":""},"phase2":{"Line1":"","Line2":"","Line3":""}}}},
-{"cms":{"index":"35","message":{"displayTime":"","phase1":{"Line1":"","Line2":"","Line3":""},"phase2":{"Line1":"","Line2":"","Line3":""}}}},
 {"cms":{"index":"24","message":{"displayTime":"","phase1":{"Line1":"","Line2":"","Line3":""},"phase2":{"Line1":"","Line2":"","Line3":""}}}},
 {"cms":{"index":"25","message":{"displayTime":"","phase1":{"Line1":"","Line2":"","Line3":""},"phase2":{"Line1":"","Line2":"","Line3":""}}}},
+{"cms":{"index":"30","message":{"displayTime":"","phase1":{"Line1":"","Line2":"","Line3":""},"phase2":{"Line1":"","Line2":"","Line3":""}}}},
+{"cms":{"index":"31","message":{"displayTime":"","phase1":{"Line1":"","Line2":"","Line3":""},"phase2":{"Line1":"","Line2":"","Line3":""}}}},
 {"cms":{"index":"32","message":{"displayTime":"","phase1":{"Line1":"","Line2":"","Line3":""},"phase2":{"Line1":"","Line2":"","Line3":""}}}},
 {"cms":{"index":"33","message":{"displayTime":"","phase1":{"Line1":"","Line2":"","Line3":""},"phase2":{"Line1":"","Line2":"","Line3":""}}}},
-{"cms":{"index":"34","message":{"displayTime":"","phase1":{"Line1":"","Line2":"","Line3":""},"phase2":{"Line1":"","Line2":"","Line3":""}}}}
+{"cms":{"index":"34","message":{"displayTime":"","phase1":{"Line1":"","Line2":"","Line3":""},"phase2":{"Line1":"","Line2":"","Line3":""}}}},
+{"cms":{"index":"35","message":{"displayTime":"","phase1":{"Line1":"","Line2":"","Line3":""},"phase2":{"Line1":"","Line2":"","Line3":""}}}},
+{"cms":{"index":"37","message":{"displayTime":"","phase1":{"Line1":"","Line2":"","Line3":""},"phase2":{"Line1":"","Line2":"","Line3":""}}}},
+{"cms":{"index":"40","message":{"displayTime":"","phase1":{"Line1":"","Line2":"","Line3":""},"phase2":{"Line1":"","Line2":"","Line3":""}}}},
+{"cms":{"index":"44","message":{"displayTime":"","phase1":{"Line1":"","Line2":"","Line3":""},"phase2":{"Line1":"","Line2":"","Line3":""}}}},
+{"cms":{"index":"51","message":{"displayTime":"","phase1":{"Line1":"","Line2":"","Line3":""},"phase2":{"Line1":"","Line2":"","Line3":""}}}},
+{"cms":{"index":"53","message":{"displayTime":"","phase1":{"Line1":"","Line2":"","Line3":""},"phase2":{"Line1":"","Line2":"","Line3":""}}}},
+{"cms":{"index":"54","message":{"displayTime":"","phase1":{"Line1":"","Line2":"","Line3":""},"phase2":{"Line1":"","Line2":"","Line3":""}}}},
+{"cms":{"index":"55","message":{"displayTime":"","phase1":{"Line1":"","Line2":"","Line3":""},"phase2":{"Line1":"","Line2":"","Line3":""}}}},
+{"cms":{"index":"57","message":{"displayTime":"","phase1":{"Line1":"","Line2":"","Line3":""},"phase2":{"Line1":"","Line2":"","Line3":""}}}},
+{"cms":{"index":"63","message":{"displayTime":"","phase1":{"Line1":"","Line2":"","Line3":""},"phase2":{"Line1":"","Line2":"","Line3":""}}}},
+{"cms":{"index":"65","message":{"displayTime":"","phase1":{"Line1":"","Line2":"","Line3":""},"phase2":{"Line1":"","Line2":"","Line3":""}}}},
+{"cms":{"index":"66","message":{"displayTime":"","phase1":{"Line1":"","Line2":"","Line3":""},"phase2":{"Line1":"","Line2":"","Line3":""}}}},
+{"cms":{"index":"69","message":{"displayTime":"","phase1":{"Line1":"","Line2":"","Line3":""},"phase2":{"Line1":"","Line2":"","Line3":""}}}},
+{"cms":{"index":"70","message":{"displayTime":"","phase1":{"Line1":"","Line2":"","Line3":""},"phase2":{"Line1":"","Line2":"","Line3":""}}}},
+{"cms":{"index":"71","message":{"displayTime":"","phase1":{"Line1":"SLOW FOR THE","Line2":"","Line3":"CONE ZONE"},"phase2":{"Line1":"","Line2":"","Line3":""}}}},
+{"cms":{"index":"72","message":{"displayTime":"","phase1":{"Line1":"","Line2":"","Line3":""},"phase2":{"Line1":"","Line2":"","Line3":""}}}},
+{"cms":{"index":"73","message":{"displayTime":"","phase1":{"Line1":"","Line2":"","Line3":""},"phase2":{"Line1":"","Line2":"","Line3":""}}}},
+{"cms":{"index":"74","message":{"displayTime":"","phase1":{"Line1":"","Line2":"","Line3":""},"phase2":{"Line1":"","Line2":"","Line3":""}}}},
+{"cms":{"index":"75","message":{"displayTime":"","phase1":{"Line1":"","Line2":"","Line3":""},"phase2":{"Line1":"","Line2":"","Line3":""}}}},
+{"cms":{"index":"76","message":{"displayTime":"","phase1":{"Line1":"","Line2":"","Line3":""},"phase2":{"Line1":"","Line2":"","Line3":""}}}},
+{"cms":{"index":"77","message":{"displayTime":"","phase1":{"Line1":"","Line2":"","Line3":""},"phase2":{"Line1":"","Line2":"","Line3":""}}}},
+{"cms":{"index":"78","message":{"displayTime":"","phase1":{"Line1":"","Line2":"","Line3":""},"phase2":{"Line1":"","Line2":"","Line3":""}}}},
+{"cms":{"index":"79","message":{"displayTime":"","phase1":{"Line1":"","Line2":"","Line3":""},"phase2":{"Line1":"","Line2":"","Line3":""}}}},
+{"cms":{"index":"80","message":{"displayTime":"","phase1":{"Line1":"","Line2":"","Line3":""},"phase2":{"Line1":"","Line2":"","Line3":""}}}},
+{"cms":{"index":"81","message":{"displayTime":"","phase1":{"Line1":"","Line2":"","Line3":""},"phase2":{"Line1":"","Line2":"","Line3":""}}}},
+{"cms":{"index":"82","message":{"displayTime":"","phase1":{"Line1":"","Line2":"","Line3":""},"phase2":{"Line1":"","Line2":"","Line3":""}}}},
+{"cms":{"index":"83","message":{"displayTime":"","phase1":{"Line1":"","Line2":"","Line3":""},"phase2":{"Line1":"","Line2":"","Line3":""}}}},
+{"cms":{"index":"84","message":{"displayTime":"","phase1":{"Line1":"","Line2":"","Line3":""},"phase2":{"Line1":"","Line2":"","Line3":""}}}},
+{"cms":{"index":"85","message":{"displayTime":"","phase1":{"Line1":"","Line2":"","Line3":""},"phase2":{"Line1":"","Line2":"","Line3":""}}}},
+{"cms":{"index":"86","message":{"displayTime":"","phase1":{"Line1":"SLOW TRAFFIC","Line2":"AHEAD","Line3":"USE CAUTION"},"phase2":{"Line1":"","Line2":"","Line3":""}}}},
+{"cms":{"index":"87","message":{"displayTime":"","phase1":{"Line1":"","Line2":"","Line3":""},"phase2":{"Line1":"","Line2":"","Line3":""}}}},
+{"cms":{"index":"88","message":{"displayTime":"","phase1":{"Line1":"","Line2":"","Line3":""},"phase2":{"Line1":"","Line2":"","Line3":""}}}},
+{"cms":{"index":"89","message":{"displayTime":"","phase1":{"Line1":"","Line2":"","Line3":""},"phase2":{"Line1":"","Line2":"","Line3":""}}}},
+{"cms":{"index":"90","message":{"displayTime":"","phase1":{"Line1":"","Line2":"","Line3":""},"phase2":{"Line1":"","Line2":"","Line3":""}}}},
+{"cms":{"index":"91","message":{"displayTime":"","phase1":{"Line1":"","Line2":"","Line3":""},"phase2":{"Line1":"","Line2":"","Line3":""}}}},
+{"cms":{"index":"92","message":{"displayTime":"","phase1":{"Line1":"","Line2":"","Line3":""},"phase2":{"Line1":"","Line2":"","Line3":""}}}},
+{"cms":{"index":"93","message":{"displayTime":"","phase1":{"Line1":"","Line2":"","Line3":""},"phase2":{"Line1":"","Line2":"","Line3":""}}}},
+{"cms":{"index":"94","message":{"displayTime":"","phase1":{"Line1":"","Line2":"","Line3":""},"phase2":{"Line1":"","Line2":"","Line3":""}}}},
+{"cms":{"index":"95","message":{"displayTime":"","phase1":{"Line1":"","Line2":"","Line3":""},"phase2":{"Line1":"","Line2":"","Line3":""}}}},
+{"cms":{"index":"96","message":{"displayTime":"","phase1":{"Line1":"","Line2":"","Line3":""},"phase2":{"Line1":"","Line2":"","Line3":""}}}},
+{"cms":{"index":"97","message":{"displayTime":"","phase1":{"Line1":"","Line2":"","Line3":""},"phase2":{"Line1":"","Line2":"","Line3":""}}}},
+{"cms":{"index":"98","message":{"displayTime":"","phase1":{"Line1":"","Line2":"","Line3":""},"phase2":{"Line1":"","Line2":"","Line3":""}}}},
+{"cms":{"index":"99","message":{"displayTime":"","phase1":{"Line1":"","Line2":"","Line3":""},"phase2":{"Line1":"","Line2":"","Line3":""}}}}
 ]}
Index: trunk/webapps/unifiedlogger/cms_watcher.py
===================================================================
--- trunk/webapps/unifiedlogger/cms_watcher.py	(revision 431)
+++ trunk/webapps/unifiedlogger/cms_watcher.py	(revision 431)
@@ -0,0 +1,103 @@
+import json, time
+from copy import deepcopy
+
+# CMS Message Watcher
+# Look for changes in the CMS message file
+# jdalbey  7/6/2019
+idList = []    # list of CMS ID's
+prevList = []  # previous messages
+currList = []  # current messages
+locationMap = {}
+
+# Utility functions
+def isEmpty(cmsitem):
+     return cmsitem == ",,,,,"
+def isFull(cmsitem):
+     return not isEmpty(cmsitem)
+
+# Read the cms message file
+def readFile():     
+     with open ("../dynamicdata/cms_messages.json",'r') as myfile:
+          jsonData=myfile.read()
+ 
+     return json.loads(jsonData)['data']
+
+# Read the static file of cms locations and create a lookup map
+def loadLocations():
+     with open ("../cptms/data_layers/cms_locations_D12.gjson",'r') as myfile:
+          jsonData=myfile.read()
+ 
+     list = json.loads(jsonData)['features']
+     # add each item to a lookup map
+     for item in list:
+          locationMap [item['id']] = item['properties']['location'] + " " + item['properties']['street']
+     
+# Setup the ID list and initialize the previous messages to empty
+def initialize():
+     loadLocations()
+     msgList = readFile()
+     global prevList, idList
+     for idx in range(0,len(msgList)):
+          idList.append(msgList[idx]['cms']['index'])
+          prevList.append(",,,,,")
+     return msgList
+
+# Extract the current messages into a list
+def extractMessages(msgList):
+     global currList
+     currList = []
+     for idx in range(0,len(msgList)):
+          currList.append(
+                    msgList[idx]['cms']['message']['phase1']['Line1'] + ',' + 
+                    msgList[idx]['cms']['message']['phase1']['Line2'] + ',' +
+                    msgList[idx]['cms']['message']['phase1']['Line3'] + ',' +
+                    msgList[idx]['cms']['message']['phase2']['Line1'] + ',' +
+                    msgList[idx]['cms']['message']['phase2']['Line2'] + ',' +
+                    msgList[idx]['cms']['message']['phase2']['Line3'])
+
+# Compare previous messages to current messages to look for changes
+def compare():
+     global prevList, currList
+     msgList = readFile()
+     extractMessages(msgList)
+     size = len(currList)
+     
+     results = []
+     # Consider each CMS message
+     for idx in range(0,size):
+          # Is a new message activated?
+          if isEmpty(prevList[idx]) and isFull(currList[idx]):
+               results.append("CMS Activated. " + locationMap[idList[idx]] + " '" + currList[idx] +"'")
+          # Is an existing message turned off?
+          if isEmpty(currList[idx]) and isFull(prevList[idx]):
+               results.append("CMS Deactivated. " + locationMap[idList[idx]])
+          # Did a message change?
+          if isFull(currList[idx]) and isFull(prevList[idx]) and currList[idx] != prevList[idx]:
+               results.append("CMS Updated. " + locationMap[idList[idx]] + " '" + currList[idx] +"'")
+
+     # Save the current list as previous
+     prevList = deepcopy(currList)
+     return results
+
+def setup():
+     msgList = initialize()
+     extractMessages(msgList)
+
+def main():
+     global currList
+     setup()
+     # Loop Forever
+     while True:
+          # Look for changed messages
+          answer = compare()
+          # Output results
+          for item in answer:
+               print item
+          # wait 
+          time.sleep(5)
+          # Get the current messages
+          extractMessages(readFile())
+
+if __name__ == "__main__":
+     main()
+     
Index: trunk/webapps/unifiedlogger/logger design.txt
===================================================================
--- trunk/webapps/unifiedlogger/logger design.txt	(revision 431)
+++ trunk/webapps/unifiedlogger/logger design.txt	(revision 431)
@@ -0,0 +1,19 @@
+FOR each plugin LOOP
+    Call setup
+END LOOP
+
+DO Forever
+
+    Get simulation time
+    Reset Output Buffer
+    FOR each plugin LOOP
+        Run the plugin process returning new log entries
+        Add simulation time and the log entries to the Output Buffer        
+    END LOOP
+    IF the Output Buffer is not empty THEN
+        Write (append) Output Buffer to unified log file 
+    END IF
+    Wait one second 
+
+END DO
+
Index: trunk/webapps/unifiedlogger/CMS watcher design.txt
===================================================================
--- trunk/webapps/unifiedlogger/CMS watcher design.txt	(revision 429)
+++ trunk/webapps/unifiedlogger/CMS watcher design.txt	(revision 431)
@@ -1,11 +1,23 @@
-For each cms in signlist
 
-  IF prev is empty and curr not empty THEN
-        print "Activated", ID, curr
-  IF curr is empty and prev not empty THEN
-        print "Deactivated", ID
-  IF curr not empty and prev not empty and curr not equal prev THEN
-        print "Updated", ID, curr
+Function Setup
+/* Assumes cms messages file is created in same order each time. */
+Create two lists, prev and curr, initially empty
+Load the cmsmessage file into prev.
 
-END
+Function processMessages
+    Load the cms message file into curr
+    Reset Results
+    For idx in 1 to length(curr)
 
+      IF prev[idx] is empty and curr[idx] not empty THEN
+            append to results: "Activated", ID, curr[idx]
+      IF curr is empty and prev not empty THEN
+            append to results: "Deactivated", ID
+      IF curr not empty and prev not empty and curr not equal prev THEN
+            append to results: "Updated", ID, curr
+
+    END
+
+    Copy curr to prev
+
+
Index: trunk/webapps/unifiedlogger/logging_service.py
===================================================================
--- trunk/webapps/unifiedlogger/logging_service.py	(revision 431)
+++ trunk/webapps/unifiedlogger/logging_service.py	(revision 431)
@@ -0,0 +1,57 @@
+import cms_watcher, time, json
+# Unified Logging Service
+# jdalbey 7/6/2019
+
+
+# Load the sim time file and extract the seconds */
+def getSimTime():
+    with open ("../dynamicdata/sim_elapsedtime.json", 'r') as myfile:
+        jsonData=myfile.read()
+         
+    seconds = json.loads(jsonData)['elapsedtime']
+    # convert seconds to H:MM:SS
+    m, s = divmod(int(seconds), 60)
+    h, m = divmod(m, 60)
+    return  "%d:%02d:%02d" % (h, m, s)    
+
+def main():
+    # List of the available plugin modules 
+    plugins = ["cms_watcher"]
+    #FOR each plugin LOOP
+    for plugin in plugins:
+        # dynamically load the setup function for this plugin
+        plugmodule = locals()[plugin]
+        setupfunc = getattr(plugmodule, 'setup')
+        #Call setup
+        setupfunc()
+    #END LOOP
+    
+    #DO Forever
+    while True:
+    #    Get simulation time
+        timeStamp = getSimTime()
+    #    Reset Output Buffer
+        output = ""
+    #    FOR each plugin LOOP
+        for plugin in plugins:
+            # dynamically load the setup function for this plugin
+            plugmodule = locals()[plugin]
+            comparefunc = getattr(plugmodule, 'compare')
+            
+    #        Run the plugin process returning new log entries
+            results = comparefunc()          # Look for changed messages
+    #    END LOOP
+    #    Append simulation time and the log entries to the Output Buffer
+        for item in results:
+            output += timeStamp + " " + item + "\n"
+    #    IF the Output Buffer has any contents THEN
+        if len(output) > 0:
+    #       Write (append) Output Buffer to unified log file 
+            print output
+    #    END IF
+    #    Wait one second
+        time.sleep(1)
+
+#END DO
+if __name__ == "__main__":
+    main()
