... | ... |
@@ -1,4 +1,4 @@ |
1 |
-#!/usr/bin/python -u |
|
1 |
+#!/usr/bin/python3 -u |
|
2 | 2 |
# The -u option above turns off block buffering of python output. This |
3 | 3 |
# assures that each error message gets individually printed to the log file. |
4 | 4 |
# |
... | ... |
@@ -35,23 +35,30 @@ |
35 | 35 |
# improved radmon device offline status handling |
36 | 36 |
# * v23 released 16 Nov 2018 by J L Owrey: improved fault handling |
37 | 37 |
# and data conversion |
38 |
+# * v24 released 14 Jun 2021 by J L Owrey; minor revisions |
|
39 |
+# |
|
38 | 40 |
#2345678901234567890123456789012345678901234567890123456789012345678901234567890 |
39 | 41 |
|
40 | 42 |
import os |
41 |
-import urllib2 |
|
42 | 43 |
import sys |
43 | 44 |
import signal |
44 | 45 |
import subprocess |
45 | 46 |
import multiprocessing |
46 | 47 |
import time |
47 | 48 |
import calendar |
49 |
+import json |
|
50 |
+from urllib.request import urlopen |
|
51 |
+ |
|
52 |
+ ### ENVIRONMENT ### |
|
48 | 53 |
|
49 | 54 |
_USER = os.environ['USER'] |
55 |
+_SERVER_MODE = "primary" |
|
56 |
+_USE_RADMON_TIMESTAMP = True |
|
50 | 57 |
|
51 | 58 |
### DEFAULT RADIATION MONITOR URL ### |
52 | 59 |
|
53 |
-# ip address of radiation monitoring device |
|
54 |
-_DEFAULT_RADIATION_MONITOR_URL = "{your radiation monitor url}" |
|
60 |
+_DEFAULT_RADIATION_MONITOR_URL = \ |
|
61 |
+ "{your radiation monitor url}" |
|
55 | 62 |
|
56 | 63 |
### FILE AND FOLDER LOCATIONS ### |
57 | 64 |
|
... | ... |
@@ -60,42 +67,40 @@ _DOCROOT_PATH = "/home/%s/public_html/radmon/" % _USER |
60 | 67 |
# folder for charts and output data file |
61 | 68 |
_CHARTS_DIRECTORY = _DOCROOT_PATH + "dynamic/" |
62 | 69 |
# location of data output file |
63 |
-_OUTPUT_DATA_FILE = _DOCROOT_PATH + "dynamic/radmonOutputData.js" |
|
70 |
+_OUTPUT_DATA_FILE = _DOCROOT_PATH + "dynamic/radmonData.js" |
|
64 | 71 |
# database that stores radmon data |
65 | 72 |
_RRD_FILE = "/home/%s/database/radmonData.rrd" % _USER |
66 | 73 |
|
67 | 74 |
### GLOBAL CONSTANTS ### |
68 | 75 |
|
69 | 76 |
# max number of failed data requests allowed |
70 |
-_MAX_FAILED_DATA_REQUESTS = 2 |
|
71 |
-# interval in seconds between data requests to radiation monitor |
|
72 |
-_DEFAULT_DATA_REQUEST_INTERVAL = 5 |
|
73 |
-# defines how often the charts get updated in seconds |
|
74 |
-_CHART_UPDATE_INTERVAL = 300 |
|
75 |
-# defines how often the database gets updated |
|
76 |
-_DATABASE_UPDATE_INTERVAL = 30 |
|
77 |
+_MAX_FAILED_DATA_REQUESTS = 3 |
|
78 |
+# interval in seconds between data requests |
|
79 |
+_DEFAULT_DATA_REQUEST_INTERVAL = 2 |
|
77 | 80 |
# number seconds to wait for a response to HTTP request |
78 | 81 |
_HTTP_REQUEST_TIMEOUT = 3 |
82 |
+ |
|
83 |
+# interval in seconds between database updates |
|
84 |
+_DATABASE_UPDATE_INTERVAL = 30 |
|
85 |
+# interval in seconds between chart updates |
|
86 |
+_CHART_UPDATE_INTERVAL = 300 |
|
79 | 87 |
# standard chart width in pixels |
80 | 88 |
_CHART_WIDTH = 600 |
81 | 89 |
# standard chart height in pixels |
82 | 90 |
_CHART_HEIGHT = 150 |
83 |
-# source of time stamp attached to output data file |
|
84 |
-_USE_RADMON_TIMESTAMP = True |
|
85 | 91 |
|
86 | 92 |
### GLOBAL VARIABLES ### |
87 | 93 |
|
88 | 94 |
# turn on or off of verbose debugging information |
89 |
-debugOption = False |
|
90 |
-verboseDebug = False |
|
95 |
+verboseMode = False |
|
96 |
+debugMode = False |
|
91 | 97 |
|
92 | 98 |
# The following two items are used for detecting system faults |
93 | 99 |
# and radiation monitor online or offline status. |
94 |
- |
|
95 | 100 |
# count of failed attempts to get data from radiation monitor |
96 | 101 |
failedUpdateCount = 0 |
97 | 102 |
# detected status of radiation monitor device |
98 |
-stationOnline = True |
|
103 |
+radmonOnline = True |
|
99 | 104 |
|
100 | 105 |
# status of reset command to radiation monitor |
101 | 106 |
remoteDeviceReset = False |
... | ... |
@@ -122,16 +127,16 @@ def setStatusToOffline(): |
122 | 127 |
Parameters: none |
123 | 128 |
Returns: nothing |
124 | 129 |
""" |
125 |
- global stationOnline |
|
130 |
+ global radmonOnline |
|
126 | 131 |
|
127 | 132 |
# Inform downstream clients by removing output data file. |
128 | 133 |
if os.path.exists(_OUTPUT_DATA_FILE): |
129 | 134 |
os.remove(_OUTPUT_DATA_FILE) |
130 | 135 |
# If the radiation monitor was previously online, then send |
131 | 136 |
# a message that we are now offline. |
132 |
- if stationOnline: |
|
133 |
- print '%s radiation monitor offline' % getTimeStamp() |
|
134 |
- stationOnline = False |
|
137 |
+ if radmonOnline: |
|
138 |
+ print('%s radiation monitor offline' % getTimeStamp()) |
|
139 |
+ radmonOnline = False |
|
135 | 140 |
##end def |
136 | 141 |
|
137 | 142 |
def terminateAgentProcess(signal, frame): |
... | ... |
@@ -145,14 +150,14 @@ def terminateAgentProcess(signal, frame): |
145 | 150 |
# Inform downstream clients by removing output data file. |
146 | 151 |
if os.path.exists(_OUTPUT_DATA_FILE): |
147 | 152 |
os.remove(_OUTPUT_DATA_FILE) |
148 |
- print '%s terminating radmon agent process' % \ |
|
149 |
- (getTimeStamp()) |
|
153 |
+ print('%s terminating radmon agent process' % \ |
|
154 |
+ (getTimeStamp())) |
|
150 | 155 |
sys.exit(0) |
151 | 156 |
##end def |
152 | 157 |
|
153 | 158 |
### PUBLIC METHODS ### |
154 | 159 |
|
155 |
-def getRadiationData(): |
|
160 |
+def getRadiationData(dData): |
|
156 | 161 |
"""Send http request to radiation monitoring device. The |
157 | 162 |
response from the device contains the radiation data as |
158 | 163 |
unformatted ascii text. |
... | ... |
@@ -160,8 +165,6 @@ def getRadiationData(): |
160 | 165 |
Returns: a string containing the radiation data if successful, |
161 | 166 |
or None if not successful |
162 | 167 |
""" |
163 |
- global remoteDeviceReset |
|
164 |
- |
|
165 | 168 |
sUrl = radiationMonitorUrl |
166 | 169 |
|
167 | 170 |
if remoteDeviceReset: |
... | ... |
@@ -170,49 +173,64 @@ def getRadiationData(): |
170 | 173 |
sUrl += "/rdata" # request data from the monitor |
171 | 174 |
|
172 | 175 |
try: |
173 |
- conn = urllib2.urlopen(sUrl, timeout=_HTTP_REQUEST_TIMEOUT) |
|
176 |
+ currentTime = time.time() |
|
177 |
+ |
|
178 |
+ response = urlopen(sUrl, timeout=_HTTP_REQUEST_TIMEOUT) |
|
179 |
+ |
|
180 |
+ if verboseMode: |
|
181 |
+ requestTime = time.time() - currentTime |
|
182 |
+ print("http request: %.4f seconds" % requestTime) |
|
174 | 183 |
|
175 |
- # Format received data into a single string. |
|
176 |
- content = "" |
|
177 |
- for line in conn: |
|
178 |
- content += line.strip() |
|
179 |
- del conn |
|
184 |
+ content = response.read().decode('utf-8') |
|
185 |
+ content = content.replace('\n', '') |
|
186 |
+ content = content.replace('\r', '') |
|
187 |
+ if content == "": |
|
188 |
+ raise Exception("empty response") |
|
180 | 189 |
|
181 |
- except Exception, exError: |
|
190 |
+ except Exception as exError: |
|
182 | 191 |
# If no response is received from the device, then assume that |
183 | 192 |
# the device is down or unavailable over the network. In |
184 | 193 |
# that case return None to the calling function. |
185 |
- if debugOption: |
|
186 |
- print "http error: %s" % exError |
|
187 |
- return None |
|
194 |
+ if verboseMode: |
|
195 |
+ print("%s getRadiationData: %s" % (getTimeStamp(), exError)) |
|
196 |
+ return False |
|
197 |
+ ##end try |
|
198 |
+ |
|
199 |
+ if debugMode: |
|
200 |
+ print(content) |
|
201 |
+ |
|
202 |
+ dData['content'] = content |
|
188 | 203 |
|
189 |
- return content |
|
204 |
+ return True |
|
190 | 205 |
##end def |
191 | 206 |
|
192 |
-def parseDataString(sData, dData): |
|
193 |
- """Parse the radiation data JSON string from the radiation |
|
194 |
- monitoring device into its component parts. |
|
207 |
+def parseDataString(dData): |
|
208 |
+ """Parse the data string returned by the radiation monitor |
|
209 |
+ into its component parts. |
|
195 | 210 |
Parameters: |
196 |
- sData - the string containing the data to be parsed |
|
197 |
- dData - a dictionary object to contain the parsed data items |
|
211 |
+ dData - a dictionary object to contain the parsed data items |
|
198 | 212 |
Returns: True if successful, False otherwise |
199 | 213 |
""" |
214 |
+ # Example radiation monitor data string |
|
215 |
+ # $,UTC=17:09:33 6/22/2021,CPS=0,CPM=26,uSv/hr=0.14,Mode=SLOW,# |
|
216 |
+ |
|
200 | 217 |
try: |
201 |
- sTmp = sData[2:-2] |
|
202 |
- lsTmp = sTmp.split(',') |
|
203 |
- except Exception, exError: |
|
204 |
- print "%s parseDataString: %s" % (getTimeStamp(), exError) |
|
218 |
+ sData = dData.pop('content') |
|
219 |
+ lData = sData[2:-2].split(',') |
|
220 |
+ except Exception as exError: |
|
221 |
+ print("%s parseDataString: %s" % (getTimeStamp(), exError)) |
|
205 | 222 |
return False |
206 | 223 |
|
207 | 224 |
# Load the parsed data into a dictionary for easy access. |
208 |
- for item in lsTmp: |
|
225 |
+ for item in lData: |
|
209 | 226 |
if "=" in item: |
210 | 227 |
dData[item.split('=')[0]] = item.split('=')[1] |
228 |
+ # Add status to dictionary object |
|
211 | 229 |
dData['status'] = 'online' |
212 | 230 |
|
213 | 231 |
# Verfy the expected number of data items have been received. |
214 | 232 |
if len(dData) != 6: |
215 |
- print "%s parse failed: corrupted data string" % getTimeStamp() |
|
233 |
+ print("%s parse failed: corrupted data string" % getTimeStamp()) |
|
216 | 234 |
return False; |
217 | 235 |
|
218 | 236 |
return True |
... | ... |
@@ -238,88 +256,60 @@ def convertData(dData): |
238 | 256 |
# that occur when the radiation monitoring device fails to |
239 | 257 |
# synchronize with a valid NTP time server. |
240 | 258 |
dData['ELT'] = time.time() |
241 |
- |
|
242 |
- dData['Mode'] = dData['Mode'].lower() |
|
259 |
+ |
|
260 |
+ dData['date'] = \ |
|
261 |
+ time.strftime("%m/%d/%Y %T", time.localtime(dData['ELT'])) |
|
262 |
+ dData['mode'] = dData.pop('Mode').lower() |
|
243 | 263 |
dData['uSvPerHr'] = '%.2f' % float(dData.pop('uSv/hr')) |
244 | 264 |
|
245 |
- except Exception, exError: |
|
246 |
- print "%s data conversion failed: %s" % (getTimeStamp(), exError) |
|
265 |
+ except Exception as exError: |
|
266 |
+ print("%s data conversion failed: %s" % (getTimeStamp(), exError)) |
|
247 | 267 |
return False |
248 | 268 |
|
249 | 269 |
return True |
250 | 270 |
##end def |
251 | 271 |
|
252 |
-def writeOutputDataFile(dData): |
|
272 |
+def writeOutputFile(dData): |
|
253 | 273 |
"""Write radiation data items to the output data file, formatted as |
254 |
- a Javascript file. This file may then be accessed and used by |
|
274 |
+ a JSON file. This file may then be accessed and used by |
|
255 | 275 |
by downstream clients, for instance, in HTML documents. |
256 | 276 |
Parameters: |
257 | 277 |
dData - a dictionary object containing the data to be written |
258 | 278 |
to the output data file |
259 | 279 |
Returns: True if successful, False otherwise |
260 | 280 |
""" |
261 |
- # Create temporary copy of output data items. |
|
281 |
+ # Create temporary copy of output data dictionary |
|
282 |
+ # and remove unnecessary items. |
|
262 | 283 |
dTemp = dict(dData) |
263 |
- # Set date to current time and data |
|
264 |
- dTemp['date'] = time.strftime("%m/%d/%Y %T", time.localtime(dData['ELT'])) |
|
265 |
- # Remove unnecessary data items. |
|
266 | 284 |
dTemp.pop('ELT') |
267 | 285 |
dTemp.pop('UTC') |
268 | 286 |
|
269 | 287 |
# Format the radmon data as string using java script object notation. |
270 |
- sData = '[{' |
|
271 |
- for key in dTemp: |
|
272 |
- sData += '\"%s\":\"%s\",' % (key, dTemp[key]) |
|
273 |
- sData = sData[:-1] + '}]\n' |
|
288 |
+ jsData = json.loads("{}") |
|
289 |
+ try: |
|
290 |
+ for key in dTemp: |
|
291 |
+ jsData.update({key:dTemp[key]}) |
|
292 |
+ jsData.update({"serverMode":"%s" % _SERVER_MODE }) |
|
293 |
+ sData = "[%s]" % json.dumps(jsData) |
|
294 |
+ except Exception as exError: |
|
295 |
+ print("%s writeOutputFile: %s" % (getTimeStamp(), exError)) |
|
296 |
+ return False |
|
274 | 297 |
|
275 |
- if verboseDebug: |
|
276 |
- print sData, |
|
298 |
+ if debugMode: |
|
299 |
+ print(sData) |
|
277 | 300 |
|
278 | 301 |
# Write the string to the output data file for use by html documents. |
279 | 302 |
try: |
280 | 303 |
fc = open(_OUTPUT_DATA_FILE, "w") |
281 | 304 |
fc.write(sData) |
282 | 305 |
fc.close() |
283 |
- except Exception, exError: |
|
284 |
- print "%s writeOutputDataFile: %s" % (getTimeStamp(), exError) |
|
306 |
+ except Exception as exError: |
|
307 |
+ print("%s writeOutputFile: %s" % (getTimeStamp(), exError)) |
|
285 | 308 |
return False |
286 | 309 |
|
287 | 310 |
return True |
288 | 311 |
## end def |
289 | 312 |
|
290 |
-def setStationStatus(updateSuccess): |
|
291 |
- """Detect if radiation monitor is offline or not available on |
|
292 |
- the network. After a set number of attempts to get data |
|
293 |
- from the monitor set a flag that the station is offline. |
|
294 |
- Parameters: |
|
295 |
- updateSuccess - a boolean that is True if data request |
|
296 |
- successful, False otherwise |
|
297 |
- Returns: nothing |
|
298 |
- """ |
|
299 |
- global failedUpdateCount, stationOnline |
|
300 |
- |
|
301 |
- if updateSuccess: |
|
302 |
- failedUpdateCount = 0 |
|
303 |
- # Set status and send a message to the log if the station was |
|
304 |
- # previously offline and is now online. |
|
305 |
- if not stationOnline: |
|
306 |
- print '%s radiation monitor online' % getTimeStamp() |
|
307 |
- stationOnline = True |
|
308 |
- if debugOption: |
|
309 |
- print 'data request successful' |
|
310 |
- else: |
|
311 |
- # The last attempt failed, so update the failed attempts |
|
312 |
- # count. |
|
313 |
- failedUpdateCount += 1 |
|
314 |
- if debugOption: |
|
315 |
- print 'data request failed' |
|
316 |
- |
|
317 |
- if failedUpdateCount >= _MAX_FAILED_DATA_REQUESTS: |
|
318 |
- # Max number of failed data requests, so set |
|
319 |
- # monitor status to offline. |
|
320 |
- setStatusToOffline() |
|
321 |
-##end def |
|
322 |
- |
|
323 | 313 |
def updateDatabase(dData): |
324 | 314 |
""" |
325 | 315 |
Update the rrdtool database by executing an rrdtool system command. |
... | ... |
@@ -337,24 +327,54 @@ def updateDatabase(dData): |
337 | 327 |
# Format the rrdtool update command. |
338 | 328 |
strCmd = "rrdtool update %s %s:%s:%s" % \ |
339 | 329 |
(_RRD_FILE, dData['ELT'], dData['CPM'], SvPerHr) |
340 |
- if verboseDebug: |
|
341 |
- print "%s" % strCmd # DEBUG |
|
330 |
+ if debugMode: |
|
331 |
+ print("%s" % strCmd) # DEBUG |
|
342 | 332 |
|
343 | 333 |
# Run the command as a subprocess. |
344 | 334 |
try: |
345 | 335 |
subprocess.check_output(strCmd, shell=True, \ |
346 | 336 |
stderr=subprocess.STDOUT) |
347 |
- except subprocess.CalledProcessError, exError: |
|
348 |
- print "%s: rrdtool update failed: %s" % \ |
|
349 |
- (getTimeStamp(), exError.output) |
|
337 |
+ except subprocess.CalledProcessError as exError: |
|
338 |
+ print("%s: rrdtool update failed: %s" % \ |
|
339 |
+ (getTimeStamp(), exError.output)) |
|
350 | 340 |
if exError.output.find("illegal attempt to update using time") > -1: |
351 | 341 |
remoteDeviceReset = True |
352 |
- print "%s: rebooting radiation monitor" % (getTimeStamp()) |
|
342 |
+ print("%s: rebooting radiation monitor" % (getTimeStamp())) |
|
353 | 343 |
return False |
344 |
+ |
|
345 |
+ if verboseMode and not debugMode: |
|
346 |
+ print("update database") |
|
347 |
+ |
|
348 |
+ return True |
|
349 |
+##end def |
|
350 |
+ |
|
351 |
+def setRadmonStatus(updateSuccess): |
|
352 |
+ """Detect if radiation monitor is offline or not available on |
|
353 |
+ the network. After a set number of attempts to get data |
|
354 |
+ from the monitor set a flag that the radmon is offline. |
|
355 |
+ Parameters: |
|
356 |
+ updateSuccess - a boolean that is True if data request |
|
357 |
+ successful, False otherwise |
|
358 |
+ Returns: nothing |
|
359 |
+ """ |
|
360 |
+ global failedUpdateCount, radmonOnline |
|
361 |
+ |
|
362 |
+ if updateSuccess: |
|
363 |
+ failedUpdateCount = 0 |
|
364 |
+ # Set status and send a message to the log if the radmon was |
|
365 |
+ # previously offline and is now online. |
|
366 |
+ if not radmonOnline: |
|
367 |
+ print('%s radiation monitor online' % getTimeStamp()) |
|
368 |
+ radmonOnline = True |
|
354 | 369 |
else: |
355 |
- if debugOption: |
|
356 |
- print 'database update sucessful' |
|
357 |
- return True |
|
370 |
+ # The last attempt failed, so update the failed attempts |
|
371 |
+ # count. |
|
372 |
+ failedUpdateCount += 1 |
|
373 |
+ |
|
374 |
+ if failedUpdateCount >= _MAX_FAILED_DATA_REQUESTS: |
|
375 |
+ # Max number of failed data requests, so set |
|
376 |
+ # monitor status to offline. |
|
377 |
+ setStatusToOffline() |
|
358 | 378 |
##end def |
359 | 379 |
|
360 | 380 |
def createGraph(fileName, dataItem, gLabel, gTitle, gStart, |
... | ... |
@@ -403,27 +423,27 @@ def createGraph(fileName, dataItem, gLabel, gTitle, gStart, |
403 | 423 |
if addTrend == 0: |
404 | 424 |
strCmd += "LINE1:dSeries#0400ff " |
405 | 425 |
elif addTrend == 1: |
406 |
- strCmd += "CDEF:smoothed=dSeries,%s,TREND LINE3:smoothed#ff0000 " \ |
|
426 |
+ strCmd += "CDEF:smoothed=dSeries,%s,TREND LINE2:smoothed#006600 " \ |
|
407 | 427 |
% trendWindow[gStart] |
408 | 428 |
elif addTrend == 2: |
409 | 429 |
strCmd += "LINE1:dSeries#0400ff " |
410 |
- strCmd += "CDEF:smoothed=dSeries,%s,TREND LINE3:smoothed#ff0000 " \ |
|
430 |
+ strCmd += "CDEF:smoothed=dSeries,%s,TREND LINE2:smoothed#006600 " \ |
|
411 | 431 |
% trendWindow[gStart] |
412 | 432 |
|
413 |
- if verboseDebug: |
|
414 |
- print "\n%s" % strCmd # DEBUG |
|
433 |
+ if debugMode: |
|
434 |
+ print("\n%s" % strCmd) # DEBUG |
|
415 | 435 |
|
416 | 436 |
# Run the formatted rrdtool command as a subprocess. |
417 | 437 |
try: |
418 | 438 |
result = subprocess.check_output(strCmd, \ |
419 | 439 |
stderr=subprocess.STDOUT, \ |
420 | 440 |
shell=True) |
421 |
- except subprocess.CalledProcessError, exError: |
|
422 |
- print "rrdtool graph failed: %s" % (exError.output) |
|
441 |
+ except subprocess.CalledProcessError as exError: |
|
442 |
+ print("rrdtool graph failed: %s" % (exError.output)) |
|
423 | 443 |
return False |
424 | 444 |
|
425 |
- if debugOption: |
|
426 |
- print "rrdtool graph: %s" % result, |
|
445 |
+ if verboseMode: |
|
446 |
+ print("rrdtool graph: %s" % result.decode('utf-8'), end='') |
|
427 | 447 |
return True |
428 | 448 |
|
429 | 449 |
##end def |
... | ... |
@@ -435,14 +455,17 @@ def generateGraphs(): |
435 | 455 |
""" |
436 | 456 |
autoScale = False |
437 | 457 |
|
458 |
+ # past 24 hours |
|
438 | 459 |
createGraph('24hr_cpm', 'CPM', 'counts\ per\ minute', |
439 | 460 |
'CPM\ -\ Last\ 24\ Hours', 'end-1day', 0, 0, 2, autoScale) |
440 | 461 |
createGraph('24hr_svperhr', 'SvperHr', 'Sv\ per\ hour', |
441 | 462 |
'Sv/Hr\ -\ Last\ 24\ Hours', 'end-1day', 0, 0, 2, autoScale) |
463 |
+ # past 4 weeks |
|
442 | 464 |
createGraph('4wk_cpm', 'CPM', 'counts\ per\ minute', |
443 | 465 |
'CPM\ -\ Last\ 4\ Weeks', 'end-4weeks', 0, 0, 2, autoScale) |
444 | 466 |
createGraph('4wk_svperhr', 'SvperHr', 'Sv\ per\ hour', |
445 | 467 |
'Sv/Hr\ -\ Last\ 4\ Weeks', 'end-4weeks', 0, 0, 2, autoScale) |
468 |
+ # past year |
|
446 | 469 |
createGraph('12m_cpm', 'CPM', 'counts\ per\ minute', |
447 | 470 |
'CPM\ -\ Past\ Year', 'end-12months', 0, 0, 2, autoScale) |
448 | 471 |
createGraph('12m_svperhr', 'SvperHr', 'Sv\ per\ hour', |
... | ... |
@@ -452,34 +475,32 @@ def generateGraphs(): |
452 | 475 |
def getCLarguments(): |
453 | 476 |
"""Get command line arguments. There are four possible arguments |
454 | 477 |
-d turns on debug mode |
455 |
- -v turns on verbose debug mode |
|
478 |
+ -v turns on verbose mode |
|
456 | 479 |
-t sets the radiation device query interval |
457 | 480 |
-u sets the url of the radiation monitoring device |
458 | 481 |
Returns: nothing |
459 | 482 |
""" |
460 |
- global debugOption, verboseDebug, dataRequestInterval, \ |
|
483 |
+ global verboseMode, debugMode, dataRequestInterval, \ |
|
461 | 484 |
radiationMonitorUrl |
462 | 485 |
|
463 | 486 |
index = 1 |
464 | 487 |
while index < len(sys.argv): |
465 |
- if sys.argv[index] == '-d': |
|
466 |
- debugOption = True |
|
467 |
- elif sys.argv[index] == '-v': |
|
468 |
- debugOption = True |
|
469 |
- verboseDebug = True |
|
488 |
+ if sys.argv[index] == '-v': |
|
489 |
+ verboseMode = True |
|
490 |
+ elif sys.argv[index] == '-d': |
|
491 |
+ verboseMode = True |
|
492 |
+ debugMode = True |
|
470 | 493 |
elif sys.argv[index] == '-t': |
471 |
- try: |
|
472 |
- dataRequestInterval = abs(int(sys.argv[index + 1])) |
|
473 |
- except: |
|
474 |
- print "invalid polling period" |
|
475 |
- exit(-1) |
|
494 |
+ dataRequestInterval = abs(int(sys.argv[index + 1])) |
|
476 | 495 |
index += 1 |
477 | 496 |
elif sys.argv[index] == '-u': |
478 | 497 |
radiationMonitorUrl = sys.argv[index + 1] |
498 |
+ if radiationMonitorUrl.find('http://') < 0: |
|
499 |
+ radiationMonitorUrl = 'http://' + radiationMonitorUrl |
|
479 | 500 |
index += 1 |
480 | 501 |
else: |
481 | 502 |
cmd_name = sys.argv[0].split('/') |
482 |
- print "Usage: %s [-d] [-t seconds] [-u url}" % cmd_name[-1] |
|
503 |
+ print("Usage: %s [-d] [-t seconds] [-u url}" % cmd_name[-1]) |
|
483 | 504 |
exit(-1) |
484 | 505 |
index += 1 |
485 | 506 |
##end def |
... | ... |
@@ -491,9 +512,10 @@ def main(): |
491 | 512 |
Returns: nothing |
492 | 513 |
""" |
493 | 514 |
signal.signal(signal.SIGTERM, terminateAgentProcess) |
515 |
+ signal.signal(signal.SIGINT, terminateAgentProcess) |
|
494 | 516 |
|
495 |
- print '%s starting up radmon agent process' % \ |
|
496 |
- (getTimeStamp()) |
|
517 |
+ print('%s starting up radmon agent process' % \ |
|
518 |
+ (getTimeStamp())) |
|
497 | 519 |
|
498 | 520 |
# last time output JSON file updated |
499 | 521 |
lastDataRequestTime = -1 |
... | ... |
@@ -507,9 +529,9 @@ def main(): |
507 | 529 |
|
508 | 530 |
## Exit with error if rrdtool database does not exist. |
509 | 531 |
if not os.path.exists(_RRD_FILE): |
510 |
- print 'rrdtool database does not exist\n' \ |
|
532 |
+ print('rrdtool database does not exist\n' \ |
|
511 | 533 |
'use createRadmonRrd script to ' \ |
512 |
- 'create rrdtool database\n' |
|
534 |
+ 'create rrdtool database\n') |
|
513 | 535 |
exit(1) |
514 | 536 |
|
515 | 537 |
## main loop |
... | ... |
@@ -517,21 +539,18 @@ def main(): |
517 | 539 |
|
518 | 540 |
currentTime = time.time() # get current time in seconds |
519 | 541 |
|
520 |
- # Every web update interval request data from the radiation |
|
542 |
+ # Every data update interval request data from the radiation |
|
521 | 543 |
# monitor and process the received data. |
522 | 544 |
if currentTime - lastDataRequestTime > dataRequestInterval: |
523 | 545 |
lastDataRequestTime = currentTime |
524 | 546 |
dData = {} |
525 |
- result = True |
|
526 | 547 |
|
527 | 548 |
# Get the data string from the device. |
528 |
- sData = getRadiationData() |
|
529 |
- if sData == None: |
|
530 |
- result = False |
|
549 |
+ result = getRadiationData(dData) |
|
531 | 550 |
|
532 | 551 |
# If successful parse the data. |
533 | 552 |
if result: |
534 |
- result = parseDataString(sData, dData) |
|
553 |
+ result = parseDataString(dData) |
|
535 | 554 |
|
536 | 555 |
# If parsing successful, convert the data. |
537 | 556 |
if result: |
... | ... |
@@ -539,18 +558,18 @@ def main(): |
539 | 558 |
|
540 | 559 |
# If conversion successful, write data to data files. |
541 | 560 |
if result: |
542 |
- writeOutputDataFile(dData) |
|
561 |
+ writeOutputFile(dData) |
|
543 | 562 |
|
544 |
- # At the rrdtool database update interval, update the database. |
|
545 |
- if currentTime - lastDatabaseUpdateTime > \ |
|
546 |
- _DATABASE_UPDATE_INTERVAL: |
|
547 |
- lastDatabaseUpdateTime = currentTime |
|
548 |
- ## Update the round robin database with the parsed data. |
|
549 |
- updateDatabase(dData) |
|
563 |
+ # At the rrdtool database update interval, update the database. |
|
564 |
+ if result and (currentTime - lastDatabaseUpdateTime > \ |
|
565 |
+ _DATABASE_UPDATE_INTERVAL): |
|
566 |
+ lastDatabaseUpdateTime = currentTime |
|
567 |
+ ## Update the round robin database with the parsed data. |
|
568 |
+ result = updateDatabase(dData) |
|
550 | 569 |
|
551 |
- # Set the station status to online or offline depending on the |
|
570 |
+ # Set the radmon status to online or offline depending on the |
|
552 | 571 |
# success or failure of the above operations. |
553 |
- setStationStatus(result) |
|
572 |
+ setRadmonStatus(result) |
|
554 | 573 |
|
555 | 574 |
|
556 | 575 |
# At the chart generation interval, generate charts. |
... | ... |
@@ -563,10 +582,13 @@ def main(): |
563 | 582 |
# the next update interval. |
564 | 583 |
|
565 | 584 |
elapsedTime = time.time() - currentTime |
566 |
- if debugOption and not verboseDebug: |
|
567 |
- pass #print |
|
568 |
- if verboseDebug: |
|
569 |
- print "processing time: %6f sec\n" % elapsedTime |
|
585 |
+ if verboseMode: |
|
586 |
+ if result: |
|
587 |
+ print("update successful: %6f sec\n" |
|
588 |
+ % elapsedTime) |
|
589 |
+ else: |
|
590 |
+ print("update failed: %6f sec\n" |
|
591 |
+ % elapsedTime) |
|
570 | 592 |
remainingTime = dataRequestInterval - elapsedTime |
571 | 593 |
if remainingTime > 0.0: |
572 | 594 |
time.sleep(remainingTime) |
... | ... |
@@ -575,8 +597,5 @@ def main(): |
575 | 597 |
## end def |
576 | 598 |
|
577 | 599 |
if __name__ == '__main__': |
578 |
- try: |
|
579 |
- main() |
|
580 |
- except KeyboardInterrupt: |
|
581 |
- print '\n', |
|
582 |
- terminateAgentProcess('KeyboardInterrupt','Module') |
|
600 |
+ main() |
|
601 |
+ |