... | ... |
@@ -5,7 +5,7 @@ |
5 | 5 |
# Module: arednsigAgent.py |
6 | 6 |
# |
7 | 7 |
# Description: This module acts as an agent between the aredn node |
8 |
-# and aredn mesh web services. The agent periodically sends an http |
|
8 |
+# and aredn mest services. The agent periodically sends an http |
|
9 | 9 |
# request to the aredn node, processes the response from |
10 | 10 |
# the node, and performs a number of operations: |
11 | 11 |
# - conversion of data items |
... | ... |
@@ -57,8 +57,8 @@ _DOCROOT_PATH = "/home/%s/public_html/arednsig/" % _USER |
57 | 57 |
_CHARTS_DIRECTORY = _DOCROOT_PATH + "dynamic/" |
58 | 58 |
# location of data output file |
59 | 59 |
_OUTPUT_DATA_FILE = _DOCROOT_PATH + "dynamic/arednsigOutputData.js" |
60 |
-# small size output data file for heartbeat signal to html docs |
|
61 |
-_SMALL_OUTPUT_FILE = _DOCROOT_PATH + "dynamic/nodeOnline.js" |
|
60 |
+# dummy output data file |
|
61 |
+_DUMMY_OUTPUT_FILE = _DOCROOT_PATH + "dynamic/nodeOnline.js" |
|
62 | 62 |
# database that stores radmon data |
63 | 63 |
_RRD_FILE = "/home/%s/database/arednsigData.rrd" % _USER |
64 | 64 |
|
... | ... |
@@ -74,6 +74,8 @@ _HTTP_REQUEST_TIMEOUT = 10 |
74 | 74 |
_CHART_WIDTH = 600 |
75 | 75 |
# standard chart height in pixels |
76 | 76 |
_CHART_HEIGHT = 150 |
77 |
+# source of time stamp attached to output data file |
|
78 |
+_USE_NODE_TIMESTAMP = True |
|
77 | 79 |
|
78 | 80 |
### GLOBAL VARIABLES ### |
79 | 81 |
|
... | ... |
@@ -89,7 +91,9 @@ failedUpdateCount = 0 |
89 | 91 |
# detected status of aredn node device |
90 | 92 |
nodeOnline = True |
91 | 93 |
|
92 |
-# network address of aredn node |
|
94 |
+# status of reset command to aredn node |
|
95 |
+remoteDeviceReset = False |
|
96 |
+# ip address of aredn node |
|
93 | 97 |
arednNodeUrl = _DEFAULT_AREDN_NODE_URL |
94 | 98 |
# frequency of data requests to aredn node |
95 | 99 |
dataRequestInterval = _DEFAULT_DATA_REQUEST_INTERVAL |
... | ... |
@@ -142,8 +146,8 @@ def setStatusToOffline(): |
142 | 146 |
# Inform downstream clients by removing output data file. |
143 | 147 |
if os.path.exists(_OUTPUT_DATA_FILE): |
144 | 148 |
os.remove(_OUTPUT_DATA_FILE) |
145 |
- if os.path.exists(_SMALL_OUTPUT_FILE): |
|
146 |
- os.remove(_SMALL_OUTPUT_FILE) |
|
149 |
+ if os.path.exists(_DUMMY_OUTPUT_FILE): |
|
150 |
+ os.remove(_DUMMY_OUTPUT_FILE) |
|
147 | 151 |
# If the aredn node was previously online, then send |
148 | 152 |
# a message that we are now offline. |
149 | 153 |
if nodeOnline: |
... | ... |
@@ -162,8 +166,8 @@ def terminateAgentProcess(signal, frame): |
162 | 166 |
# Inform downstream clients by removing output data file. |
163 | 167 |
if os.path.exists(_OUTPUT_DATA_FILE): |
164 | 168 |
os.remove(_OUTPUT_DATA_FILE) |
165 |
- if os.path.exists(_SMALL_OUTPUT_FILE): |
|
166 |
- os.remove(_SMALL_OUTPUT_FILE) |
|
169 |
+ if os.path.exists(_DUMMY_OUTPUT_FILE): |
|
170 |
+ os.remove(_DUMMY_OUTPUT_FILE) |
|
167 | 171 |
print '%s terminating arednsig agent process' % \ |
168 | 172 |
(getTimeStamp()) |
169 | 173 |
sys.exit(0) |
... | ... |
@@ -188,8 +192,8 @@ def getArednNodeData(): |
188 | 192 |
del conn |
189 | 193 |
|
190 | 194 |
except Exception, exError: |
191 |
- # If no response is received from the node, then assume that |
|
192 |
- # the node is down or unavailable over the network. In |
|
195 |
+ # If no response is received from the device, then assume that |
|
196 |
+ # the device is down or unavailable over the network. In |
|
193 | 197 |
# that case return None to the calling function. |
194 | 198 |
print "%s http error: %s" % (getTimeStamp(), exError) |
195 | 199 |
return None |
... | ... |
@@ -205,23 +209,11 @@ def parseNodeData(sData, ldData): |
205 | 209 |
into its component parts. |
206 | 210 |
Parameters: |
207 | 211 |
sData - the string containing the data to be parsed |
208 |
- ldData - a list object to contain the parsed data items |
|
212 |
+ dData - a dictionary object to contain the parsed data items |
|
209 | 213 |
Returns: True if successful, False otherwise |
210 | 214 |
""" |
211 |
- # Only interested in datapoints that have arrived during the |
|
212 |
- # current update cycle defined by the data request interval. |
|
213 |
- # The default is sixty minutes, and the node records a data point |
|
214 |
- # once a minute. Therefore, in the default case, extract the last |
|
215 |
- # sixty data points from the node's response. Otherwise, extract |
|
216 |
- # a number of datapoints equal the the data request interval |
|
217 |
- # (in minutes). |
|
218 | 215 |
iTrail = int(dataRequestInterval) |
219 | 216 |
|
220 |
- # The node response with json object containing 24 hours worth |
|
221 |
- # of datapoints. Each data point is, itself, a json object. |
|
222 |
- # The following code converts the json object to a python list |
|
223 |
- # object containing dictionary objects. Each dictionary object |
|
224 |
- # stores one data point. |
|
225 | 217 |
try: |
226 | 218 |
ldTmp = json.loads(sData[1:-1]) |
227 | 219 |
ldTmp = ldTmp[-iTrail:] |
... | ... |
@@ -230,9 +222,7 @@ def parseNodeData(sData, ldData): |
230 | 222 |
except Exception, exError: |
231 | 223 |
print "%s parse failed: %s" % (getTimeStamp(), exError) |
232 | 224 |
return False |
233 |
- |
|
234 |
- # Store the dictionary objects in the list object passed by |
|
235 |
- # reference to this function. |
|
225 |
+ |
|
236 | 226 |
del ldData[:] |
237 | 227 |
for item in ldTmp: |
238 | 228 |
ldData.append(item) |
... | ... |
@@ -245,7 +235,7 @@ def parseNodeData(sData, ldData): |
245 | 235 |
def convertData(ldData): |
246 | 236 |
"""Convert individual node signal data items as necessary. |
247 | 237 |
Parameters: |
248 |
- ldData - a list object containing the node signal data |
|
238 |
+ dData - a dictionary object containing the node signal data |
|
249 | 239 |
Returns: True if successful, False otherwise |
250 | 240 |
""" |
251 | 241 |
# parse example string |
... | ... |
@@ -255,9 +245,6 @@ def convertData(ldData): |
255 | 245 |
# |
256 | 246 |
for item in ldData: |
257 | 247 |
try: |
258 |
- # Convert data items to the required data types |
|
259 |
- # (all integer in this case). Change the dictionary |
|
260 |
- # object keys to more friendly names. |
|
261 | 248 |
item['time'] = int(item.pop('x')) / 1000 |
262 | 249 |
item['signal'] = int(item['y'][0]) |
263 | 250 |
item['noise'] = int(item['y'][1]) |
... | ... |
@@ -282,8 +269,8 @@ def updateDatabase(ldData): |
282 | 269 |
Update the rrdtool database by executing an rrdtool system command. |
283 | 270 |
Format the command using the data extracted from the aredn node |
284 | 271 |
response. |
285 |
- Parameters: ldData - a list object containing data items to be |
|
286 |
- written to the RRD file |
|
272 |
+ Parameters: dData - dictionary object containing data items to be |
|
273 |
+ written to the rr database file |
|
287 | 274 |
Returns: True if successful, False otherwise |
288 | 275 |
""" |
289 | 276 |
updateCount = 0 |
... | ... |
@@ -293,9 +280,7 @@ def updateDatabase(ldData): |
293 | 280 |
print "updating database..." |
294 | 281 |
|
295 | 282 |
for item in ldData: |
296 |
- # Throw out data points that have a time stamp earlier |
|
297 |
- # than the last entry in the round-robin database (RRD). |
|
298 |
- # rrdtool will throw an error in this case. |
|
283 |
+ |
|
299 | 284 |
if item['time'] <= lastDataPointTime: |
300 | 285 |
if verboseDebug: |
301 | 286 |
print "%s invalid timestamp: discarding data" % \ |
... | ... |
@@ -349,7 +334,7 @@ def writeOutputDataFile(sData, ldData): |
349 | 334 |
sDate = "[{\"date\":\"%s\",\"period\":\"%s\"}]" % \ |
350 | 335 |
(lastUpdate, dataRequestInterval) |
351 | 336 |
try: |
352 |
- fc = open(_SMALL_OUTPUT_FILE, "w") |
|
337 |
+ fc = open(_DUMMY_OUTPUT_FILE, "w") |
|
353 | 338 |
fc.write(sDate) |
354 | 339 |
fc.close() |
355 | 340 |
except Exception, exError: |
... | ... |
@@ -1,7 +1,6 @@ |
1 | 1 |
#!/usr/bin/python -u |
2 |
-# The -u option above turns off block buffering of python output. This |
|
3 |
-# assures that each error message gets individually printed to the |
|
4 |
-# log file. |
|
2 |
+## The -u option above turns off block buffering of python output. This assures |
|
3 |
+## that each error message gets individually printed to the log file. |
|
5 | 4 |
# |
6 | 5 |
# Module: createArednsigRrd.py |
7 | 6 |
# |
... | ... |
@@ -27,7 +26,6 @@ |
27 | 26 |
# Revision History |
28 | 27 |
# * v10 released 11 Jan 2020 by J L Owrey |
29 | 28 |
# |
30 |
-#2345678901234567890123456789012345678901234567890123456789012345678901234567890 |
|
31 | 29 |
import os |
32 | 30 |
import time |
33 | 31 |
import subprocess |
... | ... |
@@ -35,11 +33,8 @@ import subprocess |
35 | 33 |
### DEFINE FILE LOCATIONS ### |
36 | 34 |
|
37 | 35 |
_USER = os.environ['USER'] |
38 |
-# the RRD file that stores the data |
|
36 |
+# the file that stores the data |
|
39 | 37 |
_RRD_FILE = "/home/%s/database/arednsigData.rrd" % _USER |
40 |
- |
|
41 |
- ### DEFINE DATABASE GRANULARITY AND TIME SPAN ### |
|
42 |
- |
|
43 | 38 |
_RRD_SIZE_IN_DAYS = 370 # days |
44 | 39 |
_1YR_RRA_STEPS_PER_DAY = 96 |
45 | 40 |
_DATABASE_UPDATE_INTERVAL = 60 |
... | ... |
@@ -49,6 +44,7 @@ def createRrdFile(): |
49 | 44 |
Parameters: none |
50 | 45 |
Returns: True, if successful |
51 | 46 |
""" |
47 |
+ |
|
52 | 48 |
if os.path.exists(_RRD_FILE): |
53 | 49 |
print "aredn node database already exists" |
54 | 50 |
return True |
... | ... |
@@ -61,8 +57,6 @@ def createRrdFile(): |
61 | 57 |
rrd24hrNumRows = int(round(86400 / _DATABASE_UPDATE_INTERVAL)) |
62 | 58 |
rrd1yearNumRows = _1YR_RRA_STEPS_PER_DAY * _RRD_SIZE_IN_DAYS |
63 | 59 |
|
64 |
- ## Format rrdtool command to create RRD database |
|
65 |
- |
|
66 | 60 |
strFmt = ("rrdtool create %s --start now-1day --step %s " |
67 | 61 |
"DS:S:GAUGE:%s:U:U DS:N:GAUGE:%s:U:U DS:SNR:GAUGE:%s:U:U " |
68 | 62 |
"DS:RX_MCS:GAUGE:%s:U:U DS:TX_MCS:GAUGE:%s:U:U " |
... | ... |
@@ -74,10 +68,9 @@ def createRrdFile(): |
74 | 68 |
heartBeat, heartBeat, heartBeat, \ |
75 | 69 |
rrd24hrNumRows, rra1yrNumPDP, rrd1yearNumRows) |
76 | 70 |
|
77 |
- ## Run the command as a shell subprocess |
|
78 |
- |
|
79 | 71 |
print "creating aredn node database...\n\n%s\n" % strCmd |
80 | 72 |
|
73 |
+ # Spawn a sub-shell and run the command |
|
81 | 74 |
try: |
82 | 75 |
subprocess.check_output(strCmd, stderr=subprocess.STDOUT, \ |
83 | 76 |
shell=True) |
... | ... |
@@ -24,6 +24,7 @@ h4 { |
24 | 24 |
width: 750px; |
25 | 25 |
text-align: center; |
26 | 26 |
margin: auto; |
27 |
+ /*border: 1px solid black;*/ |
|
27 | 28 |
} |
28 | 29 |
.datetime { |
29 | 30 |
font: bold 22px arial, sans-serif; |
... | ... |
@@ -40,7 +41,6 @@ h4 { |
40 | 41 |
text-align: center; |
41 | 42 |
display: table-cell; |
42 | 43 |
vertical-align: middle; |
43 |
- /*border: 1px solid black;*/ |
|
44 | 44 |
} |
45 | 45 |
.dataItems { |
46 | 46 |
padding: 2px; |
... | ... |
@@ -60,10 +60,10 @@ img.chart { |
60 | 60 |
text-align: left; |
61 | 61 |
padding: 10px; |
62 | 62 |
} |
63 |
-span.chartNav { |
|
63 |
+span.navContainer { |
|
64 | 64 |
margin: auto; |
65 | 65 |
} |
66 |
-ul.chartNav { |
|
66 |
+ul.navElement { |
|
67 | 67 |
list-style-type: none; |
68 | 68 |
margin: 10px; |
69 | 69 |
padding: 0; |
... | ... |
@@ -71,20 +71,25 @@ ul.chartNav { |
71 | 71 |
background-color: #bbb; |
72 | 72 |
text-align: center; |
73 | 73 |
} |
74 |
-li.chartNav { |
|
74 |
+li.navElement { |
|
75 | 75 |
display: inline-block; |
76 | 76 |
font: bold 18px arial, sans-serif; |
77 | 77 |
color: black; |
78 | 78 |
} |
79 |
-text.chartNav:hover { |
|
79 |
+span.navElement:hover { |
|
80 | 80 |
background-color: #333; |
81 | 81 |
cursor: pointer; |
82 | 82 |
color: white; |
83 | 83 |
} |
84 |
-text.chartNav { |
|
84 |
+span.navElement { |
|
85 | 85 |
display: inline-block; |
86 | 86 |
padding: 8px 12px; |
87 | 87 |
} |
88 |
+#iframe_a { |
|
89 |
+ border:none; |
|
90 |
+ width:100%; |
|
91 |
+ height:450px; |
|
92 |
+} |
|
88 | 93 |
</style> |
89 | 94 |
</head> |
90 | 95 |
|
... | ... |
@@ -97,9 +102,9 @@ style="text-decoration:none" target="_new"> |
97 | 102 |
KA7JLO Aredn Node Signal</a></h2> |
98 | 103 |
<h3>Last Updated</h3> |
99 | 104 |
<div class="datetime"> |
100 |
-<text id="date"></text> |
|
105 |
+<span id="date"></span> |
|
101 | 106 |
|
102 |
-<text id="time"></text> |
|
107 |
+<span id="time"></span> |
|
103 | 108 |
</div> |
104 | 109 |
|
105 | 110 |
<div class="rowContainer"> |
... | ... |
@@ -109,43 +114,51 @@ Status:<br> |
109 | 114 |
Page updates every: |
110 | 115 |
</div> |
111 | 116 |
<div class="dataItems"> |
112 |
-<text id="status"></text><br> |
|
113 |
-<text id="period"></text> minutes |
|
117 |
+<span id="status"></span><br> |
|
118 |
+<span id="period"></span> minutes |
|
114 | 119 |
</div> |
115 | 120 |
</div> |
116 | 121 |
</div> |
117 | 122 |
|
118 |
-<span class="chartNav"> |
|
119 |
-<ul class="chartNav"> |
|
120 |
-<li class="chartNav">Select charts:</li> |
|
121 |
-<li class="chartNav"><text class="chartNav" onclick="setChartPeriod(1)"> |
|
122 |
-24 hours</text></li> |
|
123 |
-<li class="chartNav"><text class="chartNav" onclick="setChartPeriod(2)"> |
|
124 |
-4 weeks</text></li> |
|
125 |
-<li class="chartNav"><text class="chartNav" onclick="setChartPeriod(3)"> |
|
126 |
-12 months</text></li> |
|
123 |
+<span class="navContainer"> |
|
124 |
+<ul class="navElement"> |
|
125 |
+<li class="navElement">Select charts:</li> |
|
126 |
+<li class="navElement"><span class="navElement" onclick="setChartPeriod(1)"> |
|
127 |
+24 hours</span></li> |
|
128 |
+<li class="navElement"><span class="navElement" onclick="setChartPeriod(2)"> |
|
129 |
+4 weeks</span></li> |
|
130 |
+<li class="navElement"><span class="navElement" onclick="setChartPeriod(3)"> |
|
131 |
+12 months</span></li> |
|
132 |
+<li class="navElement"><span class="navElement" onclick="setChartPeriod(0)"> |
|
133 |
+Custom...</span></li> |
|
127 | 134 |
</ul> |
128 | 135 |
</span> |
129 |
-<br> |
|
130 | 136 |
|
131 |
-<div class="chartContainer"> |
|
132 |
-<img class="chart" id="snrChart"> |
|
137 |
+<div class="rowContainer" id="customChartsContainer" style="display:none;"> |
|
138 |
+<div class="currentDataCell"> |
|
139 |
+<form id="fmDateSelector" action="arednsig.php" method="post" |
|
140 |
+ target="iframe_a"> |
|
141 |
+<label for="beginDate">Begin Date: </label> |
|
142 |
+<input id="beginDate" name="beginDate" type="date" value="mm/dd/yyyy" /> |
|
143 |
+<label for="endDate">End Date: </label> |
|
144 |
+<input id="endDate" name="endDate" type="date" value="mm/dd/yyyy" /> |
|
145 |
+<br><br> |
|
146 |
+<input type="button" onclick="getCustomCharts()" value="Get Charts"> |
|
147 |
+</form> |
|
148 |
+<span id="errorMsg"></span><br> |
|
149 |
+<iframe id="iframe_a" name="iframe_a"></iframe> |
|
133 | 150 |
</div> |
134 |
- |
|
135 |
-<div class="chartContainer"> |
|
136 |
-<img class="chart" id="signalChart"> |
|
137 | 151 |
</div> |
138 | 152 |
|
139 |
-<div class="chartContainer"> |
|
140 |
-<img class="chart" id="noiseChart"> |
|
141 |
-</div> |
|
153 |
+<br> |
|
142 | 154 |
|
155 |
+<div class="rowContainer" id="stockChartsContainer"> |
|
143 | 156 |
<div class="chartContainer"> |
144 |
-<img class="chart" id="rxrateChart"> |
|
157 |
+<img class="chart" id="signalChart"> |
|
145 | 158 |
</div> |
146 |
- |
|
147 | 159 |
<div class="chartContainer"> |
148 |
-<img class="chart" id="txrateChart"> |
|
160 |
+<img class="chart" id="snrChart"> |
|
161 |
+</div> |
|
149 | 162 |
</div> |
150 | 163 |
|
151 | 164 |
<div class="notes"> |
... | ... |
@@ -175,25 +188,32 @@ var nodeDataUrl = "dynamic/nodeOnline.js"; |
175 | 188 |
/* Global DOM objects */ |
176 | 189 |
|
177 | 190 |
// Chart elements |
178 |
-var snrChart = document.getElementById("snrChart"); |
|
179 | 191 |
var signalChart = document.getElementById("signalChart"); |
180 |
-var noiseChart = document.getElementById("noiseChart"); |
|
181 |
-var rxrateChart = document.getElementById("rxrateChart"); |
|
182 |
-var txrateChart = document.getElementById("txrateChart"); |
|
192 |
+var snrChart = document.getElementById("snrChart"); |
|
183 | 193 |
|
184 | 194 |
// Text elements |
185 | 195 |
var dateElmt = document.getElementById("date"); |
186 | 196 |
var timeElmt = document.getElementById("time"); |
187 | 197 |
var statusElmt = document.getElementById("status"); |
188 | 198 |
var periodElmt = document.getElementById("period"); |
199 |
+ |
|
200 |
+// Document elements |
|
201 |
+var customChartsContainer = document.getElementById("customChartsContainer"); |
|
202 |
+var stockChartsContainer = document.getElementById("stockChartsContainer"); |
|
203 |
+var chartContainer = document.getElementsByClassName("chartContainer"); |
|
204 |
+var fmDateSelector = document.getElementById("fmDateSelector"); |
|
205 |
+var beginDate = document.getElementById("beginDate"); |
|
206 |
+var endDate = document.getElementById("endDate"); |
|
207 |
+var errorMsg = document.getElementById("errorMsg"); |
|
208 |
+ |
|
189 | 209 |
/* Global objects */ |
190 | 210 |
|
191 | 211 |
var httpRequest = new XMLHttpRequest(); |
192 | 212 |
|
193 | 213 |
/* Global variables */ |
194 | 214 |
|
195 |
-var graphPeriod; |
|
196 |
-var graphRefreshRate = 10; // chart refresh rate in minutes |
|
215 |
+var chartPeriod = 1; |
|
216 |
+var chartRefreshRate = 10; // chart refresh rate in minutes |
|
197 | 217 |
|
198 | 218 |
function main() { |
199 | 219 |
/* Register call back function to process http requests */ |
... | ... |
@@ -209,9 +229,9 @@ function main() { |
209 | 229 |
displayOfflineStatus(); |
210 | 230 |
}; |
211 | 231 |
|
232 |
+ initializeDateSelector(); |
|
212 | 233 |
getNodeData(); |
213 |
- graphPeriod = 1; |
|
214 |
- getNodeGraphs(); |
|
234 |
+ getNodeCharts(); |
|
215 | 235 |
} |
216 | 236 |
|
217 | 237 |
function getNodeData() { |
... | ... |
@@ -221,15 +241,22 @@ function getNodeData() { |
221 | 241 |
} |
222 | 242 |
|
223 | 243 |
function setChartPeriod(n) { |
224 |
- graphPeriod = n; |
|
225 |
- getNodeGraphs(); |
|
244 |
+ chartPeriod = n; |
|
245 |
+ if (n == 0) { |
|
246 |
+ customChartsContainer.style.display = "block"; |
|
247 |
+ stockChartsContainer.style.display = "none"; |
|
248 |
+ } else { |
|
249 |
+ customChartsContainer.style.display = "none"; |
|
250 |
+ stockChartsContainer.style.display = "block"; |
|
251 |
+ getNodeCharts(); |
|
252 |
+ } |
|
226 | 253 |
} |
227 | 254 |
|
228 |
-function getNodeGraphs() { |
|
255 |
+function getNodeCharts() { |
|
229 | 256 |
var d = new Date; |
230 | 257 |
var pfx; |
231 | 258 |
|
232 |
- switch(graphPeriod) { |
|
259 |
+ switch(chartPeriod) { |
|
233 | 260 |
case 1: |
234 | 261 |
pfx = "24hr_"; |
235 | 262 |
break; |
... | ... |
@@ -241,10 +268,7 @@ function getNodeGraphs() { |
241 | 268 |
break; |
242 | 269 |
} |
243 | 270 |
signalChart.src = "dynamic/" + pfx + "signal.png?ver=" + d.getTime(); |
244 |
- noiseChart.src = "dynamic/" + pfx + "noise.png?ver=" + d.getTime(); |
|
245 | 271 |
snrChart.src = "dynamic/" + pfx + "snr.png?ver=" + d.getTime(); |
246 |
- rxrateChart.src = "dynamic/" + pfx + "rx_rate.png?ver=" + d.getTime(); |
|
247 |
- txrateChart.src = "dynamic/" + pfx + "tx_rate.png?ver=" + d.getTime(); |
|
248 | 272 |
} |
249 | 273 |
|
250 | 274 |
function displayData(dataItem) { |
... | ... |
@@ -259,29 +283,51 @@ function displayData(dataItem) { |
259 | 283 |
localTimeZone = localDate.getTimezoneOffset() / 60; |
260 | 284 |
dateElmt.innerHTML = date; |
261 | 285 |
timeElmt.innerHTML = hourminute + |
262 |
- " <small>(GMT+" + localTimeZone + ")</small>"; |
|
286 |
+ " <small>(GMT+" + localTimeZone + ")</small>"; |
|
263 | 287 |
|
264 | 288 |
statusElmt.innerHTML = "Online"; |
265 | 289 |
statusElmt.style.color = "green"; |
266 | 290 |
|
267 |
- graphRefreshRate = dataItem.period; |
|
268 |
- periodElmt.innerHTML = graphRefreshRate; |
|
269 |
- setInterval(getNodeData, 60000 * graphRefreshRate); |
|
270 |
- setInterval(getNodeGraphs, 60000 * graphRefreshRate); |
|
291 |
+ chartRefreshRate = dataItem.period; |
|
292 |
+ periodElmt.innerHTML = chartRefreshRate; |
|
293 |
+ setInterval(getNodeData, 60000 * chartRefreshRate); |
|
294 |
+ setInterval(getNodeCharts, 60000 * chartRefreshRate); |
|
271 | 295 |
} |
272 | 296 |
|
273 | 297 |
function displayOfflineStatus() { |
274 | 298 |
var d = new Date(); |
275 | 299 |
localTimeZone = d.getTimezoneOffset() / 60; |
276 | 300 |
dateElmt.innerHTML = (d.getMonth() + 1) + "/" + d.getDate() + "/" + |
277 |
- d.getFullYear(); |
|
301 |
+ d.getFullYear(); |
|
278 | 302 |
timeElmt.innerHTML = d.getHours() + ":" + d.getMinutes() + |
279 |
- " <small>(GMT+" + localTimeZone + ")</small>"; |
|
303 |
+ " <small>(GMT+" + localTimeZone + ")</small>"; |
|
280 | 304 |
periodElmt.innerHTML = "?"; |
281 | 305 |
statusElmt.innerHTML = "offline"; |
282 | 306 |
statusElmt.style.color = "red"; |
283 | 307 |
} |
284 | 308 |
|
309 |
+function initializeDateSelector() { |
|
310 |
+ var d = new Date(); |
|
311 |
+ |
|
312 |
+ var dEnd = new Date(d.getFullYear(), |
|
313 |
+ d.getMonth(), d.getDate() - 0); |
|
314 |
+ |
|
315 |
+ var dBegin = new Date(d.getFullYear(), |
|
316 |
+ d.getMonth(), d.getDate() - 1); |
|
317 |
+ |
|
318 |
+ var strBegin = dBegin.getFullYear() + "-" + (dBegin.getMonth() + 1) + |
|
319 |
+ "-" + dBegin.getDate(); |
|
320 |
+ var strEnd = dEnd.getFullYear() + "-" + (dEnd.getMonth() + 1) + |
|
321 |
+ "-" + dEnd.getDate(); |
|
322 |
+ |
|
323 |
+ beginDate.valueAsDate = dBegin; |
|
324 |
+ endDate.valueAsDate = dEnd; |
|
325 |
+ //errorMsg.innerHTML = strBegin + " thru " + strEnd; |
|
326 |
+} |
|
327 |
+ |
|
328 |
+function getCustomCharts() { |
|
329 |
+ fmDateSelector.submit(); |
|
330 |
+} |
|
285 | 331 |
</script> |
286 | 332 |
|
287 | 333 |
</body> |