Browse code

revisions 20151229

Jeff Owrey authored on 12/30/2015 04:41:17
Showing 2 changed files
... ...
@@ -373,7 +373,7 @@ void listenForEthernetClients()
373 373
         sBuffer[i] = 0;
374 374
       }
375 375
       // request for JSON string response
376
-      if(strcmp(sBuffer, "GET /jsdata ") == 0) {
376
+      if(strcmp(sBuffer, "GET /rdata ") == 0) {
377 377
         iMode = 1;
378 378
       }
379 379
       // request for standard HTML document
... ...
@@ -388,20 +388,19 @@ void listenForEthernetClients()
388 388
     client.println(F("HTTP/1.1 200 OK\n"        \
389 389
                    "Content-Type: text/html\n"  \
390 390
                    "Connnection: close\n"       \
391
-               //  "Refresh: 10\n"              \
392 391
                    "\n"                         \
393 392
                    ));
394 393
                    
395 394
     switch (iMode) {
396 395
       case 0:
397 396
         // Respond to an invalid URL received from the client
398
-        client.print(F("<!DOCTYPE HTML>\n" \
399
-                       "<HTML><HEAD><TITLE>Radmon</TITLE></HEAD>"  \
400
-                       "<BODY><H2>Invalid URL</H2>"  \
401
-                       "<P> You have reached a server at an unknown " \
402
-                       "URL.  If you think you made this request in error " \
403
-                       "please disconnect and try your request again.</P>" \
404
-                       "</BODY></HTML>"));
397
+        client.print(F("<!DOCTYPE html>\n" \
398
+                       "<html><head><title>DIY Radmon</title></head>"  \
399
+                       "<body><h2>Invalid URL</h2>" \
400
+                       "<p>You have reached a server at an unknown URL.</p>" \
401
+                       "<p>If you think you made this call in error,<br>" \
402
+                       "please hangup and try your call again.</p>" \
403
+                       "</body></html>"));
405 404
         break;
406 405
       case 1:
407 406
         transmitJson(client);
... ...
@@ -434,33 +433,33 @@ void transmitWebPage(EthernetClient client)
434 433
    * Send the actual HTML page the user will see in their web
435 434
    * browser.
436 435
   */
437
-  client.print(F("<!DOCTYPE HTML>\n" \
438
-                 "<HTML><HEAD><TITLE>Radmon</TITLE>"  \
439
-                 "</HEAD><BODY><H2>Radiation Monitor</H2>" \
440
-                 "<P><A HREF=\"http://intravisions.com/radmon/\">" \
441
-                 "<I>IntraVisions.com/radmon</I></A></P>" \
442
-                 "<HR><FONT SIZE=\"+1\">"));
443
-  /* Data Items */             
444
-  client.print(F("<PRE>UTC&#9;"));
436
+  client.print(F("<!DOCTYPE html>\n" \
437
+                 "<html><head><title>DIY Radmon</title>"  \
438
+                 "<style>pre{font-size:140%;}</style>" \
439
+                 "</head><body><h2>DIY Radiation Monitor</h2>" \
440
+                 "<p><a href=\"http://intravisions.com/radmon/\">" \
441
+                 "<i>intravisions.com</i></a></p><hr>" \
442
+                 "<p><pre>UTC&#9;"));
443
+  /* Data Items */
445 444
   client.print(strtok(strBuffer, " "));
446 445
   client.print(F(" "));
447 446
   client.print(strtok(NULL, ", "));
448
-  client.print(F("<BR>"));
447
+  client.print(F("<br>"));
449 448
   client.print(strtok(NULL, ", "));
450 449
   client.print(F("&#9;"));
451 450
   client.print(strtok(NULL, ", "));
452
-  client.print(F("<BR>"));
451
+  client.print(F("<br>"));
453 452
   client.print(strtok(NULL, ", "));
454 453
   client.print(F("&#9;"));
455 454
   client.print(strtok(NULL, ", "));
456
-  client.print(F("<BR>"));
455
+  client.print(F("<br>"));
457 456
   client.print(strtok(NULL, ", "));
458 457
   client.print(F("&#9;"));
459 458
   client.print(strtok(NULL, ", "));
460
-  client.print(F("<BR>"));
459
+  client.print(F("<br>"));
461 460
   client.print(F("Mode&#9;"));
462 461
   client.print(strtok(NULL, ", "));
463
-  client.print(F("<BR></PRE></FONT></BODY></HTML>"));
462
+  client.print(F("<br></pre></p></body></html>"));
464 463
   return;
465 464
 }  
466 465
 
... ...
@@ -475,7 +474,7 @@ void transmitJson(EthernetClient client) {
475 474
   /*
476 475
    * Format and transmit a JSON compatible data string.
477 476
    */
478
-  client.print(F("[{\"radmon\":\"$,UTC="));
477
+  client.print(F("$,UTC="));
479 478
   client.print(strtok(strBuffer, " "));
480 479
   client.print(F(" "));
481 480
   client.print(strtok(NULL, ", "));
... ...
@@ -494,7 +493,7 @@ void transmitJson(EthernetClient client) {
494 493
   client.print(F(","));
495 494
   client.print(F("Mode="));
496 495
   client.print(strtok(NULL, ", "));
497
-  client.print(F(",#,\"}]"));
496
+  client.print(F(",#"));
498 497
   return;
499 498
 }
500 499
 
... ...
@@ -56,9 +56,11 @@ _HTTP_REQUEST_TIMEOUT = 5 # number seconds to wait for a response to HTTP reques
56 56
    ### GLOBAL VARIABLES ###
57 57
 
58 58
 webUpdateInterval = _DEFAULT_WEB_DATA_UPDATE_INTERVAL  # web update frequency
59
-deviceUrl = "http://192.168.1.8"  # radiation monitor network address
59
+deviceUrl = "{your URL}"  # radiation monitor network address
60
+deviceOnline = True
60 61
 debugOption = False
61 62
 
63
+
62 64
   ###  PRIVATE METHODS  ###
63 65
 
64 66
 def getTimeStamp():
... ...
@@ -70,89 +72,97 @@ def getTimeStamp():
70 72
     return time.strftime( "%Y/%m/%d %T", time.localtime() )
71 73
 ##end def
72 74
 
73
-def sendOffLineStatusMessage():
74
-    """Sets the status of the the upstream device to "offline" and sends
75
+def setOfflineStatus(dData):
76
+    """Set the status of the the upstream device to "offline" and sends
75 77
        blank data to the downstream clients.
76
-       Parameters: none
78
+       Parameters:
79
+           dData - dictionary object containing weather data
77 80
        Returns nothing.
78 81
     """
79
-    sTmp = "\"date\":\"\",\"CPS\":\"\",\"CPM\":\"\"," \
80
-           "\"uSvPerHr\":\"\",\"Mode\":\"\",\"status\":\"offline\""
81
-
82
-    lsTmp = sTmp.split(',')
83
-    lsTmp[0] = "\"date\":\"%s\"" % getTimeStamp()
84
-    writeOutputDataFile(lsTmp)
82
+    global deviceOnline
83
+
84
+    # If the radiation monitor was previously online, then send a message
85
+    # that we are now offline.
86
+    if deviceOnline:
87
+        print "%s: radmon offline" % getTimeStamp()
88
+        deviceOnline = False
89
+
90
+    # Set data items to blank.
91
+    dData['UTC'] = ''
92
+    dData['CPM'] = ''
93
+    dData['CPS'] = ''
94
+    dData['uSvPerHr'] = ''
95
+    dData['Mode'] = ''
96
+    dData['status'] = 'offline'
97
+
98
+    writeOutputDataFile(dData)
85 99
     return
86 100
 ##end def
87 101
 
88 102
   ###  PUBLIC METHODS  ###
89 103
 
90 104
 def getRadmonData(deviceUrl, HttpRequestTimeout):
91
-        """Send http request to radiation monitoring device.  The response
92
-           from the device contains the radiation data.  The data is formatted
93
-           as an html document.
94
-        Parameters: 
95
-            deviceUrl - url of radiation monitoring device
96
-            HttpRequesttimeout - how long to wait for device
97
-                                 to respond to http request
98
-        Returns a string containing the radiation data, or None if
99
-        not successful.
100
-        """
101
-        content = ""
102
-        try:
103
-            conn = urllib2.urlopen(deviceUrl + "/jsdata", timeout=HttpRequestTimeout)
104
-        except Exception, exError:
105
-            # If no response is received from the device, then assume that
106
-            # the device is down or unavailable over the network.  In
107
-            # that case set the status of the device to offline.
108
-            print "%s: device offline: %s" % \
109
-                                (getTimeStamp(), exError)
110
-            return None
111
-        else:
112
-            for line in conn:
113
-                content += line.strip()
114
-            if len(content) == 0:
115
-                print "%s: HTTP download failed: null content" % \
116
-                    (getTimeStamp())
117
-                return None
118
-            del conn
119
-            return content
105
+    """Send http request to radiation monitoring device.  The response
106
+       from the device contains the radiation data.  The data is formatted
107
+       as an html document.
108
+    Parameters: 
109
+        deviceUrl - url of radiation monitoring device
110
+        HttpRequesttimeout - how long to wait for device
111
+                             to respond to http request
112
+    Returns a string containing the radiation data, or None if
113
+    not successful.
114
+    """
115
+    global deviceOnline
116
+
117
+    try:
118
+        conn = urllib2.urlopen(deviceUrl + "/rdata", timeout=HttpRequestTimeout)
119
+    except Exception, exError:
120
+        # If no response is received from the device, then assume that
121
+        # the device is down or unavailable over the network.  In
122
+        # that case set the status of the device to offline.
123
+        if debugOption:
124
+            print "getRadmonData: %s\n" % exError
125
+        return None
126
+
127
+    # If the radiation monitor was previously offline, then send a message
128
+    # that we are now online.
129
+    if not deviceOnline:
130
+        print "%s radmon online" % getTimeStamp()
131
+        deviceOnline = True
132
+
133
+    # Format received data into a single string.
134
+    content = ""
135
+    for line in conn:
136
+         content += line.strip()
137
+    del conn
138
+    return content
120 139
 ##end def
121 140
 
122
-def parseDataString(sData, lsData, dData):
141
+def parseDataString(sData, dData):
123 142
     """Parse the radiation data JSON string from the radiation 
124 143
        monitoring device into its component parts.  
125 144
        Parameters:
126 145
            sData - the string containing the data to be parsed
127
-          lsData - a list object to contain the parsed data items
128 146
            dData - a dictionary object to contain the parsed data items
129 147
        Returns true if successful, false otherwise.
130 148
     """
131
-    # Clear data array in preparation for loading reformatted data.
132
-    while len(lsData) > 0:
133
-        elmt = lsData.pop(0)
134
-
135 149
     try:
136
-        dTmp = json.loads(sData[1:-1])
137
-        sTmp = dTmp['radmon'].encode('ascii', 'ignore')
150
+        sTmp = sData[2:-2]
138 151
         lsTmp = sTmp.split(',')
139
-        lsData.extend(lsTmp)
140 152
     except Exception, exError:
141
-        print "%s parse failed: %s" % (getTimeStamp(), exError)
153
+        print "%s parseDataString: %s" % (getTimeStamp(), exError)
142 154
         return False
143 155
 
144
-    # Since the device responded, set the status to online.
145
-    lsData.insert(-2, "status=online")
146
-
147 156
     # Load the parsed data into a dictionary for easy access.
148
-    for item in lsData:
157
+    for item in lsTmp:
149 158
         if "=" in item:
150 159
             dData[item.split('=')[0]] = item.split('=')[1]
160
+    dData['status'] = 'online'
151 161
 
152 162
     return True
153 163
 ##end def
154 164
 
155
-def convertData(lsData, dData):
165
+def convertData(dData):
156 166
     """Convert individual radiation data items as necessary.
157 167
        Parameters:
158 168
            lsData - a list object containing the radiation data
... ...
@@ -166,47 +176,44 @@ def convertData(lsData, dData):
166 176
         ts_utc = time.strptime(dData['UTC'], "%H:%M:%S %m/%d/%Y")
167 177
         local_sec = calendar.timegm(ts_utc)
168 178
         dData['UTC'] = local_sec
169
-    except:
170
-        print "%s invalid time: %s" % (getTimeStamp(), utc)
171
-        result = False
172
-
173
-    # Clear data array in preparation for loading reformatted data.
174
-    while len(lsData) > 0:
175
-        elmt = lsData.pop(0)
176 179
 
177
-    lsData.append("\"UTC\":\"%s\"" % dData['UTC'])
178
-    lsData.append("\"CPS\":\"%s\"" % dData['CPS'])
179
-    lsData.append("\"CPM\":\"%s\"" % dData['CPM'])
180
-    lsData.append("\"uSvPerHr\":\"%s\"" % dData['uSv/hr'])
181
-    lsData.append("\"Mode\":\"%s\"" % dData['Mode'].lower())
182
-    lsData.append("\"status\":\"%s\"" % dData['status'])
180
+        dData['uSvPerHr'] = dData.pop('uSv/hr')
181
+        dData['Mode'] = dData.pop('Mode').lower()
182
+    except Exception, exError:
183
+        print "%s convertData: %s" % (getTimeStamp(), exError)
184
+        result = False
183 185
 
184 186
     return result
185 187
 ##end def
186 188
 
187
-def writeOutputDataFile(lsData):
189
+def writeOutputDataFile(dData):
188 190
     """Convert individual weather string data items as necessary.
189 191
        Parameters:
190 192
            lsData - a list object containing the data to be written
191 193
                     to the JSON file
192 194
        Returns true if successful, false otherwise.
193 195
     """
194
-    # Convert the list object to a string.
195
-    sTmp = ','.join(lsData)
196
+    # Set date to current time and data
197
+    dData['date'] = getTimeStamp()
196 198
 
197
-    # Apply JSON formatting to the string and write it to a
198
-    # file for use by html documents.
199
-    sData = "[{%s}]\n" % (sTmp)
199
+    # Format the weather data as string using java script object notation.
200
+    sData = '[{'
201
+    for key in dData:
202
+        sData += "\"%s\":\"%s\"," % (key, dData[key])
203
+    sData = sData[:-1] + '}]\n'
200 204
 
205
+    # Write the string to the output data file for use by html documents.
201 206
     try:
202 207
         fc = open(_OUTPUT_DATA_FILE, "w")
203 208
         fc.write(sData)
204 209
         fc.close()
205 210
     except Exception, exError:
206
-        print "%s: write to JSON file failed: %s" % \
207
-                             (getTimeStamp(), exError)
211
+        print "%s writeOutputDataFile: %s" % (getTimeStamp(), exError)
208 212
         return False
209 213
 
214
+    if debugOption:
215
+        print sData
216
+
210 217
     return True
211 218
 ## end def
212 219
 
... ...
@@ -220,7 +227,7 @@ def updateDatabase(dData):
220 227
     Returns true if successful, false otherwise.
221 228
     """
222 229
     # The RR database stores whole units, so convert uSv to Sv.   
223
-    Svvalue = float(dData['uSv/hr']) * 1.0E-06 # convert micro-Sieverts to Sieverts
230
+    Svvalue = float(dData['uSvPerHr']) * 1.0E-06 # convert micro-Sieverts to Sieverts
224 231
 
225 232
     # Create the rrdtool update command.
226 233
     strCmd = "rrdtool update %s %s:%s:%s" % \
... ...
@@ -328,7 +335,7 @@ def main():
328 335
 
329 336
     lastChartUpdateTime = - 1 # last time charts generated
330 337
     lastDatabaseUpdateTime = -1 # last time the rrdtool database updated
331
-    lastWebDataUpdateTime = -1 # last time output JSON file updated
338
+    lastWebUpdateTime = -1 # last time output JSON file updated
332 339
     dData = {}  # dictionary object for temporary data storage
333 340
     lsData = [] # list object for temporary data storage
334 341
 
... ...
@@ -351,28 +358,27 @@ def main():
351 358
 
352 359
         # At the radiation device query interval request and process
353 360
         # the data from the device.
354
-        if currentTime - lastWebDataUpdateTime > webUpdateInterval:
355
-            llastWebDataUpdateTime = currentTime
361
+        if currentTime - lastWebUpdateTime > webUpdateInterval:
362
+            lastWebUpdateTime = currentTime
356 363
             result = True
357 364
 
358 365
             # Get the data string from the device.
359 366
             sData = getRadmonData(deviceUrl, _HTTP_REQUEST_TIMEOUT)
360 367
             if sData == None:
361
-                sendOffLineStatusMessage()
368
+                setOfflineStatus(dData)
362 369
                 result = False
363 370
 
364 371
             # If successful parse the data.
365 372
             if result:
366
-                result = parseDataString(sData, lsData, dData)
373
+                result = parseDataString(sData, dData)
367 374
 
368 375
             # If parsing successful, convert the data.
369 376
             if result:
370
-                result = convertData(lsData, dData)
377
+                result = convertData(dData)
371 378
 
372 379
             # If conversion successful, write data to output file.
373 380
             if result:
374
-                lsData[0] = "\"date\":\"%s\"" % getTimeStamp()
375
-                writeOutputDataFile(lsData)
381
+                writeOutputDataFile(dData)
376 382
 
377 383
         # At the rrdtool database update interval, update the database.
378 384
         if currentTime - lastDatabaseUpdateTime > _DATABASE_UPDATE_INTERVAL: