... | ... |
@@ -15,7 +15,7 @@ |
15 | 15 |
# - write the processed weather data to a JSON file for use by html |
16 | 16 |
# documents |
17 | 17 |
# |
18 |
-# Copyright 2018 Jeff Owrey |
|
18 |
+# Copyright 2015 Jeff Owrey |
|
19 | 19 |
# This program is free software: you can redistribute it and/or modify |
20 | 20 |
# it under the terms of the GNU General Public License as published by |
21 | 21 |
# the Free Software Foundation, either version 3 of the License, or |
... | ... |
@@ -34,9 +34,10 @@ |
34 | 34 |
# * v21 released 27 Nov 2017 by J L Owrey; bug fixes; updates |
35 | 35 |
# * v22 released 03 Mar 2018 by J L Owrey; improved code readability; |
36 | 36 |
# improved radmon device offline status handling |
37 |
-# |
|
37 |
+# * v23 released 15 Nov 2018 by J L Owrey; improved system fault |
|
38 |
+# handling and radiation monitor offline handling |
|
38 | 39 |
|
39 |
-_MIRROR_SERVER = False |
|
40 |
+_MIRROR_SERVER = True |
|
40 | 41 |
|
41 | 42 |
import os |
42 | 43 |
import urllib2 |
... | ... |
@@ -52,9 +53,10 @@ _USER = os.environ['USER'] |
52 | 53 |
### DEFAULT RADIATION MONITOR URL ### |
53 | 54 |
|
54 | 55 |
# ip address of radiation monitoring device |
55 |
-_DEFAULT_RADIATION_MONITOR_URL = "{your radiation monitor url}" |
|
56 |
+_DEFAULT_RADIATION_MONITOR_URL = "http://192.168.1.24" |
|
56 | 57 |
# url if this is a mirror server |
57 |
-_PRIMARY_SERVER_URL = "{your primary server url}" |
|
58 |
+_PRIMARY_SERVER_URL = "http://73.157.139.23:7361" \ |
|
59 |
+ "/~pi/radmon/dynamic/radmonInputData.dat" |
|
58 | 60 |
|
59 | 61 |
### FILE AND FOLDER LOCATIONS ### |
60 | 62 |
|
... | ... |
@@ -89,10 +91,10 @@ _CHART_HEIGHT = 150 |
89 | 91 |
|
90 | 92 |
# turn on or off of verbose debugging information |
91 | 93 |
debugOption = False |
92 |
-# online status of radiation monitor |
|
93 |
-radiationMonitorOnline = True |
|
94 |
-# number of unsuccessful http requests |
|
95 |
-failedDataRequestCount = 0 |
|
94 |
+# used for detecting system faults and radiation monitor |
|
95 |
+# online or offline status |
|
96 |
+failedUpdateCount = 0 |
|
97 |
+stationOnline = True |
|
96 | 98 |
# status of reset command to radiation monitor |
97 | 99 |
remoteDeviceReset = False |
98 | 100 |
# ip address of radiation monitor |
... | ... |
@@ -111,33 +113,28 @@ def getTimeStamp(): |
111 | 113 |
return time.strftime( "%m/%d/%Y %T", time.localtime() ) |
112 | 114 |
##end def |
113 | 115 |
|
114 |
-def setOfflineStatus(dData): |
|
116 |
+def setStatusToOffline(): |
|
115 | 117 |
"""Set the status of the the upstream device to "offline" and sends |
116 | 118 |
blank data to the downstream clients. |
117 | 119 |
Parameters: |
118 | 120 |
dData - dictionary object containing weather data |
119 | 121 |
Returns nothing. |
120 | 122 |
""" |
121 |
- global radiationMonitorOnline, failedDataRequestCount |
|
123 |
+ global stationOnline |
|
122 | 124 |
|
123 | 125 |
if os.path.exists(_INPUT_DATA_FILE): |
124 | 126 |
os.remove(_INPUT_DATA_FILE) |
125 |
- |
|
126 |
- if failedDataRequestCount < _MAX_FAILED_DATA_REQUESTS - 1: |
|
127 |
- failedDataRequestCount += 1 |
|
128 |
- return |
|
127 |
+ if os.path.exists(_OUTPUT_DATA_FILE): |
|
128 |
+ os.remove(_OUTPUT_DATA_FILE) |
|
129 | 129 |
|
130 | 130 |
# If the radiation monitor was previously online, then send a message |
131 | 131 |
# that we are now offline. |
132 |
- if radiationMonitorOnline: |
|
133 |
- print "%s: radiation monitor offline" % getTimeStamp() |
|
134 |
- radiationMonitorOnline = False |
|
135 |
- if os.path.exists(_OUTPUT_DATA_FILE): |
|
136 |
- os.remove(_OUTPUT_DATA_FILE) |
|
137 |
- return |
|
132 |
+ if stationOnline: |
|
133 |
+ print '%s radiation monitor offline' % getTimeStamp() |
|
134 |
+ stationOnline = False |
|
138 | 135 |
##end def |
139 | 136 |
|
140 |
-def signal_term_handler(signal, frame): |
|
137 |
+def terminateAgentProcess(signal, frame): |
|
141 | 138 |
"""Send message to log when process killed |
142 | 139 |
Parameters: signal, frame - sigint parameters |
143 | 140 |
Returns: nothing |
... | ... |
@@ -164,8 +161,7 @@ def getRadiationData(): |
164 | 161 |
Returns a string containing the radiation data, or None if |
165 | 162 |
not successful. |
166 | 163 |
""" |
167 |
- global radiationMonitorOnline, failedDataRequestCount, \ |
|
168 |
- remoteDeviceReset |
|
164 |
+ global remoteDeviceReset |
|
169 | 165 |
|
170 | 166 |
if _MIRROR_SERVER: |
171 | 167 |
sUrl = _PRIMARY_SERVER_URL |
... | ... |
@@ -193,13 +189,6 @@ def getRadiationData(): |
193 | 189 |
print "http error: %s" % exError |
194 | 190 |
return None |
195 | 191 |
|
196 |
- # If the radiation monitor was previously offline, then send a message |
|
197 |
- # that we are now online. |
|
198 |
- if not radiationMonitorOnline: |
|
199 |
- print "%s radiation monitor online" % getTimeStamp() |
|
200 |
- radiationMonitorOnline = True |
|
201 |
- |
|
202 |
- failedDataRequestCount = 0 |
|
203 | 192 |
return content |
204 | 193 |
##end def |
205 | 194 |
|
... | ... |
@@ -322,6 +311,28 @@ def writeInputDataFile(sData): |
322 | 311 |
return True |
323 | 312 |
##end def |
324 | 313 |
|
314 |
+def setStationStatus(updateSuccess): |
|
315 |
+ global failedUpdateCount, stationOnline |
|
316 |
+ |
|
317 |
+ if updateSuccess: |
|
318 |
+ failedUpdateCount = 0 |
|
319 |
+ # Set status and send a message to the log if the station was |
|
320 |
+ # previously offline and is now online. |
|
321 |
+ if not stationOnline: |
|
322 |
+ print '%s radiation monitor online' % getTimeStamp() |
|
323 |
+ stationOnline = True |
|
324 |
+ if debugOption: |
|
325 |
+ print 'radiation update successful' |
|
326 |
+ else: |
|
327 |
+ failedUpdateCount += 1 |
|
328 |
+ if debugOption: |
|
329 |
+ print 'radiation update failed' |
|
330 |
+ |
|
331 |
+ if failedUpdateCount >= _MAX_FAILED_DATA_REQUESTS: |
|
332 |
+ setStatusToOffline() |
|
333 |
+##end def |
|
334 |
+ |
|
335 |
+ |
|
325 | 336 |
def updateDatabase(dData): |
326 | 337 |
""" |
327 | 338 |
Updates the rrdtool database by executing an rrdtool system command. |
... | ... |
@@ -486,7 +497,7 @@ def main(): |
486 | 497 |
Parameters: none |
487 | 498 |
Returns nothing. |
488 | 499 |
""" |
489 |
- signal.signal(signal.SIGTERM, signal_term_handler) |
|
500 |
+ signal.signal(signal.SIGTERM, terminateAgentProcess) |
|
490 | 501 |
|
491 | 502 |
print '%s starting up radmon agent process' % \ |
492 | 503 |
(getTimeStamp()) |
... | ... |
@@ -523,7 +534,6 @@ def main(): |
523 | 534 |
# Get the data string from the device. |
524 | 535 |
sData = getRadiationData() |
525 | 536 |
if sData == None: |
526 |
- setOfflineStatus(dData) |
|
527 | 537 |
result = False |
528 | 538 |
|
529 | 539 |
# If successful parse the data. |
... | ... |
@@ -538,15 +548,18 @@ def main(): |
538 | 548 |
if result: |
539 | 549 |
writeInputDataFile(sData) |
540 | 550 |
writeOutputDataFile(dData) |
541 |
- if debugOption: |
|
542 |
- print "http request successful" |
|
543 | 551 |
|
544 | 552 |
# At the rrdtool database update interval, update the database. |
545 | 553 |
if currentTime - lastDatabaseUpdateTime > \ |
546 | 554 |
_DATABASE_UPDATE_INTERVAL: |
547 | 555 |
lastDatabaseUpdateTime = currentTime |
548 | 556 |
## Update the round robin database with the parsed data. |
549 |
- result = updateDatabase(dData) |
|
557 |
+ updateDatabase(dData) |
|
558 |
+ |
|
559 |
+ # Set the station status to online or offline depending on the |
|
560 |
+ # success or failure of the above operations. |
|
561 |
+ setStationStatus(result) |
|
562 |
+ |
|
550 | 563 |
|
551 | 564 |
# At the chart generation interval, generate charts. |
552 | 565 |
if currentTime - lastChartUpdateTime > _CHART_UPDATE_INTERVAL: |
... | ... |
@@ -559,7 +572,8 @@ def main(): |
559 | 572 |
|
560 | 573 |
elapsedTime = time.time() - currentTime |
561 | 574 |
if debugOption: |
562 |
- print "processing time: %6f sec\n" % elapsedTime |
|
575 |
|
|
576 |
+ #print "processing time: %6f sec\n" % elapsedTime |
|
563 | 577 |
remainingTime = dataRequestInterval - elapsedTime |
564 | 578 |
if remainingTime > 0.0: |
565 | 579 |
time.sleep(remainingTime) |
... | ... |
@@ -571,9 +585,5 @@ if __name__ == '__main__': |
571 | 585 |
try: |
572 | 586 |
main() |
573 | 587 |
except KeyboardInterrupt: |
574 |
- print '\n%s terminating radmon agent process' % \ |
|
575 |
- (getTimeStamp()) |
|
576 |
- if os.path.exists(_OUTPUT_DATA_FILE): |
|
577 |
- os.remove(_OUTPUT_DATA_FILE) |
|
578 |
- if os.path.exists(_INPUT_DATA_FILE): |
|
579 |
- os.remove(_INPUT_DATA_FILE) |
|
588 |
+ print '\n', |
|
589 |
+ terminateAgentProcess('KeyboardInterrupt','Module') |
... | ... |
@@ -201,6 +201,9 @@ function main() { |
201 | 201 |
displayOfflineStatus(); |
202 | 202 |
} |
203 | 203 |
}; |
204 |
+ httpRequest.ontimeout = function(e) { |
|
205 |
+ displayOfflineStatus(); |
|
206 |
+ }; |
|
204 | 207 |
|
205 | 208 |
getRadmonData(); |
206 | 209 |
graphPeriod = 1; |
... | ... |
@@ -211,6 +214,7 @@ function main() { |
211 | 214 |
|
212 | 215 |
function getRadmonData() { |
213 | 216 |
httpRequest.open("GET", radmonDataUrl, true); |
217 |
+ httpRequest.timeout = 3000; |
|
214 | 218 |
httpRequest.send(); |
215 | 219 |
} |
216 | 220 |
|
... | ... |
@@ -261,11 +265,11 @@ function displayData(dataItem) { |
261 | 265 |
if (dataItem.status == "online") { |
262 | 266 |
status_e.style.color = "green"; |
263 | 267 |
} else { |
264 |
- status_e.style.color = "red"; |
|
268 |
+ displayOffLineStatus(); |
|
265 | 269 |
} |
266 | 270 |
} |
267 | 271 |
|
268 |
-function displayOfflineStatus(dataItem) { |
|
272 |
+function displayOfflineStatus() { |
|
269 | 273 |
var d = new Date(); |
270 | 274 |
localTimeZone = d.getTimezoneOffset() / 60; |
271 | 275 |
date_e.innerHTML = (d.getMonth() + 1) + "/" + d.getDate() + "/" + d.getFullYear(); |
... | ... |
@@ -274,7 +278,7 @@ function displayOfflineStatus(dataItem) { |
274 | 278 |
cpm_e.innerHTML = ""; |
275 | 279 |
cps_e.innerHTML = ""; |
276 | 280 |
uSvPerHr_e.innerHTML = ""; |
277 |
- mode_e.innerHTML = ""; |
|
281 |
+ mode_e.innerHTML = " "; |
|
278 | 282 |
status_e.innerHTML = "offline"; |
279 | 283 |
status_e.style.color = "red"; |
280 | 284 |
} |