Browse code

fix version number

gandolf authored on 03/31/2020 17:51:53
Showing 9 changed files
1 1
deleted file mode 100755
... ...
@@ -1,27 +0,0 @@
1
-#!/bin/bash
2
-#
3
-# The monitor url can look something like http://192.168.1.155, or
4
-# something linke http://radiationMonitor.domain.com depending on
5
-# whether your local network uses a domain name server.
6
-#
7
-
8
-APP_PATH="/home/$USER/bin"
9
-LOG_PATH="/home/$USER/log"
10
-
11
-AGENT_NAME="[a]rednsigAgent.py"
12
-NODE_URL="http://localnode:8080/cgi-bin/signal.json"
13
-
14
-POLLING_INTERVAL="60"
15
-
16
-PROCESS_ID="$(ps x | awk -v a=$AGENT_NAME '$7 ~ a {print $1}')"
17
-
18
-if [ -n "$PROCESS_ID" ]; then
19
-  if [ "$1" != "-q" ]; then
20
-    printf "arednsig agent running [%s]\n" $PROCESS_ID
21
-  fi
22
-else
23
-  printf "starting up arednsig agent\n"
24
-  cd $APP_PATH
25
-  $(./$AGENT_NAME -u $NODE_URL -p $POLLING_INTERVAL >> \
26
- $LOG_PATH/arednsigAgent.log 2>&1 &)
27
-fi
28 0
deleted file mode 100755
... ...
@@ -1,14 +0,0 @@
1
-#!/bin/bash
2
-# Stop the radmon agent process and clean up environment.
3
-
4
-
5
-AGENT_NAME="[a]rednsigAgent.py"
6
-
7
-PROCESS_ID="$(ps x | awk -v a=$AGENT_NAME '$7 ~ a {print $1}')"
8
-
9
-if [ -n "$PROCESS_ID" ]; then
10
-  printf "killing arednsig agent [%s]\n" $PROCESS_ID
11
-  kill $PROCESS_ID
12
-else
13
-  echo arednsig agent not running
14
-fi
15 0
deleted file mode 100755
... ...
@@ -1,701 +0,0 @@
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 log file.
4
-#
5
-# Module: arednsigAgent.py
6
-#
7
-# Description: This module acts as an agent between the aredn node
8
-# and aredn mest services.  The agent periodically sends an http
9
-# request to the aredn node, processes the response from
10
-# the node, and performs a number of operations:
11
-#     - conversion of data items
12
-#     - update a round robin (rrdtool) database with the node data
13
-#     - periodically generate graphic charts for display in html documents
14
-#     - write the processed node status to a JSON file for use by html
15
-#       documents
16
-#
17
-# Copyright 2020 Jeff Owrey
18
-#    This program is free software: you can redistribute it and/or modify
19
-#    it under the terms of the GNU General Public License as published by
20
-#    the Free Software Foundation, either version 3 of the License, or
21
-#    (at your option) any later version.
22
-#
23
-#    This program is distributed in the hope that it will be useful,
24
-#    but WITHOUT ANY WARRANTY; without even the implied warranty of
25
-#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
26
-#    GNU General Public License for more details.
27
-#
28
-#    You should have received a copy of the GNU General Public License
29
-#    along with this program.  If not, see http://www.gnu.org/license.
30
-#
31
-# Revision History
32
-#   * v20 released 11 Jan 2020 by J L Owrey; first release
33
-#   * v21 released 13 Feb 2020 by J L Owrey; fixed bug occuring when node
34
-#     powers on and signal data memory is empty.  Data points with N/A data
35
-#     are discarded.
36
-#
37
-#2345678901234567890123456789012345678901234567890123456789012345678901234567890
38
-
39
-import os
40
-import urllib2
41
-import sys
42
-import signal
43
-import subprocess
44
-import multiprocessing
45
-import time
46
-import json
47
-
48
-_USER = os.environ['USER']
49
-_HOSTNAME = os.uname()[1]
50
-
51
-   ### DEFAULT AREDN NODE URL ###
52
-
53
-# set url of the aredn node
54
-
55
-_DEFAULT_AREDN_NODE_URL = "http://localnode:8080/cgi-bin/signal.json"
56
-
57
-    ### FILE AND FOLDER LOCATIONS ###
58
-
59
-# folder for containing dynamic data objects
60
-_DOCROOT_PATH = "/home/%s/public_html/arednsig/" % _USER
61
-# folder for charts and output data file
62
-_CHARTS_DIRECTORY = _DOCROOT_PATH + "dynamic/"
63
-# location of data output file
64
-_OUTPUT_DATA_FILE = _DOCROOT_PATH + "dynamic/arednsigOutputData.js"
65
-# dummy output data file
66
-_DUMMY_OUTPUT_FILE = _DOCROOT_PATH + "dynamic/nodeOnline.js"
67
-# database that stores node data
68
-_RRD_FILE = "/home/%s/database/arednsigData.rrd" % _USER
69
-
70
-    ### GLOBAL CONSTANTS ###
71
-
72
-# max number of failed data requests allowed
73
-_MAX_FAILED_DATA_REQUESTS = 0
74
-# interval in minutes between data requests to the aredn node
75
-_DEFAULT_DATA_REQUEST_INTERVAL = 60
76
-# number seconds to wait for a response to HTTP request
77
-_HTTP_REQUEST_TIMEOUT = 10
78
-# standard chart width in pixels
79
-_CHART_WIDTH = 600
80
-# standard chart height in pixels
81
-_CHART_HEIGHT = 150
82
-# Set this to True only if this server is intended to relay raw
83
-# node data to a mirror server.
84
-_RELAY_SERVER = False
85
-
86
-   ### GLOBAL VARIABLES ###
87
-
88
-# turn on or off of verbose debugging information
89
-debugOption = False
90
-verboseDebug = False
91
-
92
-# The following two items are used for detecting system faults
93
-# and aredn node online or offline status.
94
-
95
-# count of failed attempts to get data from aredn node
96
-failedUpdateCount = 0
97
-# detected status of aredn node device
98
-nodeOnline = True
99
-
100
-# ip address of aredn node
101
-arednNodeUrl = _DEFAULT_AREDN_NODE_URL
102
-# frequency of data requests to aredn node
103
-dataRequestInterval = _DEFAULT_DATA_REQUEST_INTERVAL
104
-# last node request time
105
-lastDataPointTime = -1
106
-
107
-  ###  PRIVATE METHODS  ###
108
-
109
-def getTimeStamp():
110
-    """
111
-    Set the error message time stamp to the local system time.
112
-    Parameters: none
113
-    Returns: string containing the time stamp
114
-    """
115
-    return time.strftime( "%m/%d/%Y %T", time.localtime() )
116
-##end def
117
-
118
-def getLastDataPointTime():
119
-    """
120
-    Get the timestamp of the most recent update to the round robin
121
-    database.
122
-    Parameters: none
123
-    Returns: string epoch time stamp of the last rrd update
124
-    """
125
-    strCmd = "rrdtool lastupdate %s" % \
126
-             (_RRD_FILE)
127
-
128
-    # Run the command as a subprocess.
129
-    try:
130
-        result = subprocess.check_output(strCmd, shell=True,  \
131
-                             stderr=subprocess.STDOUT)
132
-    except subprocess.CalledProcessError, exError:
133
-        print "%s: rrdtool update failed: %s" % \
134
-                    (getTimeStamp(), exError.output)
135
-        return None
136
-
137
-    # Return just the epoch time stamp of the last rrd update
138
-    return int((result.split('\n')[-2]).split(':')[0])
139
-##end def
140
-
141
-def setStatusToOffline():
142
-    """Set the detected status of the aredn node to
143
-       "offline" and inform downstream clients by removing input
144
-       and output data files.
145
-       Parameters: none
146
-       Returns: nothing
147
-    """
148
-    global nodeOnline
149
-
150
-    # Inform downstream clients by removing output data file.
151
-    if os.path.exists(_OUTPUT_DATA_FILE):
152
-       os.remove(_OUTPUT_DATA_FILE)
153
-    if os.path.exists(_DUMMY_OUTPUT_FILE):
154
-       os.remove(_DUMMY_OUTPUT_FILE)
155
-    # If the aredn node was previously online, then send
156
-    # a message that we are now offline.
157
-    if nodeOnline:
158
-        print '%s aredn node offline' % getTimeStamp()
159
-    nodeOnline = False
160
-##end def
161
-
162
-def terminateAgentProcess(signal, frame):
163
-    """Send a message to log when the agent process gets killed
164
-       by the operating system.  Inform downstream clients
165
-       by removing input and output data files.
166
-       Parameters:
167
-           signal, frame - dummy parameters
168
-       Returns: nothing
169
-    """
170
-    # Inform downstream clients by removing output data file.
171
-    if os.path.exists(_OUTPUT_DATA_FILE):
172
-       os.remove(_OUTPUT_DATA_FILE)
173
-    if os.path.exists(_DUMMY_OUTPUT_FILE):
174
-       os.remove(_DUMMY_OUTPUT_FILE)
175
-    print '%s terminating arednsig agent process' % \
176
-              (getTimeStamp())
177
-    sys.exit(0)
178
-##end def
179
-
180
-  ###  PUBLIC METHODS  ###
181
-
182
-def getArednNodeData():
183
-    """Send http request to aredn node.  The response from the
184
-       node contains the node signal data as unformatted ascii text.
185
-       Parameters: none
186
-       Returns: a string containing the node signal data if successful,
187
-                or None if not successful
188
-    """
189
-    try:
190
-        conn = urllib2.urlopen(arednNodeUrl, timeout=_HTTP_REQUEST_TIMEOUT)
191
-
192
-        # Format received data into a single string.
193
-        content = ""
194
-        for line in conn:
195
-            content += line.strip()
196
-        del conn
197
-
198
-    except Exception, exError:
199
-        # If no response is received from the device, then assume that
200
-        # the device is down or unavailable over the network.  In
201
-        # that case return None to the calling function.
202
-        print "%s http error: %s" % (getTimeStamp(), exError)
203
-        return None
204
-
205
-    if verboseDebug:
206
-        print "http request successful: %d bytes" % len(content)
207
-
208
-    return content
209
-##end def
210
-
211
-def parseNodeData(sData, ldData):
212
-    """Parse the node  signal data JSON string from the aredn node
213
-       into its component parts.  
214
-       Parameters:
215
-           sData - the string containing the data to be parsed
216
-           dData - a dictionary object to contain the parsed data items
217
-       Returns: True if successful, False otherwise
218
-    """
219
-    iTrail = int(dataRequestInterval)
220
-
221
-    try:
222
-        ldTmp = json.loads(sData[1:-1])
223
-        ldTmp = ldTmp[-iTrail:]
224
-        if len(ldTmp) != iTrail:
225
-            #raise Exception("truncated list")
226
-            pass
227
-    except Exception, exError:
228
-        print "%s parse failed: %s" % (getTimeStamp(), exError)
229
-        return False
230
-    
231
-    del ldData[:]
232
-    for item in ldTmp:
233
-        ldData.append(item)
234
-
235
-    if verboseDebug:
236
-        print "parse successful: %d data points" % len(ldData)
237
-    return True
238
-##end def
239
-
240
-def convertData(ldData):
241
-    """Convert individual node signal data items as necessary.
242
-       Parameters:
243
-           dData - a dictionary object containing the node signal data
244
-       Returns: True if successful, False otherwise
245
-    """
246
-    # parse example string
247
-    # {u'tx_mcs': u'15', u'rx_mcs': u'15', u'm': 47,
248
-    #  u'label': u'01/10/2020 22:17:01', u'rx_rate': u'130',
249
-    #  u'y': [-48, -95], u'x': 1578694621000, u'tx_rate': u'130'}
250
-    #
251
-    index = 0
252
-    while index < len(ldData):
253
-        item = ldData[index]
254
-        try:
255
-            item['time'] = int(item.pop('x')) / 1000
256
-            item['signal'] = int(item['y'][0])
257
-            item['noise'] = int(item['y'][1])
258
-            item['snr'] = int(item.pop('m'))
259
-            item['rx_mcs'] = int(item.pop('rx_mcs'))
260
-            item['tx_mcs'] = int(item.pop('tx_mcs'))
261
-            item['rx_rate'] = int(item.pop('rx_rate'))
262
-            item['tx_rate'] = int(item.pop('tx_rate'))
263
-            item.pop('y')
264
-            item.pop('label')
265
-        except Exception, exError:
266
-            print "%s convert data item failed: %s" % (getTimeStamp(), exError)
267
-            print "discarding %s" % item
268
-            #return False
269
-            ldData.pop(index)
270
-        else:
271
-            index += 1
272
-    ##end for
273
-
274
-    if len(ldData) > 0:
275
-        if verboseDebug:
276
-            print "convert data successful"
277
-        return True
278
-    else:
279
-        print "convert data failed"
280
-        return False
281
-##end def
282
-
283
-def updateDatabase(ldData):
284
-    """
285
-    Update the rrdtool database by executing an rrdtool system command.
286
-    Format the command using the data extracted from the aredn node
287
-    response.   
288
-    Parameters: dData - dictionary object containing data items to be
289
-                        written to the rr database file
290
-    Returns: True if successful, False otherwise
291
-    """
292
-    updateCount = 0
293
-    lastDataPointTime = getLastDataPointTime()
294
-
295
-    if verboseDebug:
296
-         print "updating database..."
297
-
298
-    for item in ldData:
299
-
300
-        if item['time'] <= lastDataPointTime:
301
-            if verboseDebug:
302
-                print "%s invalid timestamp: discarding data" % \
303
-                      (getTimeStamp())
304
-            continue
305
-
306
-        # Format the rrdtool update command.
307
-        strFmt = "rrdtool update %s %s:%s:%s:%s:%s:%s:%s:%s"
308
-        strCmd = strFmt % (_RRD_FILE, item['time'], item['signal'], \
309
-                 item['noise'], item['snr'], item['rx_mcs'], \
310
-                 item['tx_mcs'], item['rx_rate'], item['tx_rate'])
311
-
312
-        if verboseDebug:
313
-            print "%s" % strCmd # DEBUG
314
-
315
-        # Run the command as a subprocess.
316
-        try:
317
-            subprocess.check_output(strCmd, shell=True,  \
318
-                                 stderr=subprocess.STDOUT)
319
-        except subprocess.CalledProcessError, exError:
320
-            print "%s: rrdtool update failed: %s" % \
321
-                        (getTimeStamp(), exError.output)
322
-            return False
323
-        updateCount += 1
324
-    ##end for
325
-
326
-    if debugOption:
327
-        print '%s added %d data points to database' % \
328
-              (getTimeStamp(), updateCount)
329
-    return True
330
-##end def
331
-
332
-def writeOutputDataFile(sData, ldData):
333
-    """Write node data items to the output data file, formatted as 
334
-       a Javascript file.  This file may then be accessed and used by
335
-       by downstream clients, for instance, in HTML documents.
336
-       Parameters:
337
-           sData - a string object containing the data to be written
338
-                   to the output data file
339
-       Returns: True if successful, False otherwise
340
-    """
341
-    # Write file for use by html clients.  The following two
342
-    # data items are sent to the client file.
343
-    #    * The last database update date and time
344
-    #    * The data request interval
345
-    lastUpdate = time.strftime( "%m.%d.%Y %T", 
346
-                                time.localtime(ldData[-1]['time']) )
347
-    sDate = "[{\"date\":\"%s\",\"period\":\"%s\"}]" % \
348
-           (lastUpdate, dataRequestInterval)
349
-    try:
350
-        fc = open(_DUMMY_OUTPUT_FILE, "w")
351
-        fc.write(sDate)
352
-        fc.close()
353
-    except Exception, exError:
354
-        print "%s write node file failed: %s" % (getTimeStamp(), exError)
355
-        return False
356
-
357
-    if _RELAY_SERVER:
358
-        # Write the entire node data response to the output data file.
359
-        try:
360
-            fc = open(_OUTPUT_DATA_FILE, "w")
361
-            fc.write(sData)
362
-            fc.close()
363
-        except Exception, exError:
364
-            print "%s write output file failed: %s" % \
365
-                  (getTimeStamp(), exError)
366
-            return False
367
-        if verboseDebug:
368
-            print "write output data file: %d bytes" % len(sData)
369
-
370
-    return True
371
-## end def
372
-
373
-def setNodeStatus(updateSuccess):
374
-    """Detect if aredn node is offline or not available on
375
-       the network. After a set number of attempts to get data
376
-       from the node set a flag that the node is offline.
377
-       Parameters:
378
-           updateSuccess - a boolean that is True if data request
379
-                           successful, False otherwise
380
-       Returns: nothing
381
-    """
382
-    global failedUpdateCount, nodeOnline
383
-
384
-    if updateSuccess:
385
-        failedUpdateCount = 0
386
-        # Set status and send a message to the log if the node was
387
-        # previously offline and is now online.
388
-        if not nodeOnline:
389
-            print '%s aredn node online' % getTimeStamp()
390
-            nodeOnline = True
391
-    else:
392
-        # The last attempt failed, so update the failed attempts
393
-        # count.
394
-        failedUpdateCount += 1
395
-
396
-    if failedUpdateCount > _MAX_FAILED_DATA_REQUESTS:
397
-        # Max number of failed data requests, so set
398
-        # node status to offline.
399
-        setStatusToOffline()
400
-##end def
401
-
402
-def createGraph(fileName, dataItem, gLabel, gTitle, gStart,
403
-                lower, upper, addTrend, autoScale):
404
-    """Uses rrdtool to create a graph of specified node data item.
405
-       Parameters:
406
-           fileName - name of file containing the graph
407
-           dataItem - data item to be graphed
408
-           gLabel - string containing a graph label for the data item
409
-           gTitle - string containing a title for the graph
410
-           gStart - beginning time of the graphed data
411
-           lower - lower bound for graph ordinate #NOT USED
412
-           upper - upper bound for graph ordinate #NOT USED
413
-           addTrend - 0, show only graph data
414
-                      1, show only a trend line
415
-                      2, show a trend line and the graph data
416
-           autoScale - if True, then use vertical axis auto scaling
417
-               (lower and upper parameters are ignored), otherwise use
418
-               lower and upper parameters to set vertical axis scale
419
-       Returns: True if successful, False otherwise
420
-    """
421
-    gPath = _CHARTS_DIRECTORY + fileName + ".png"
422
-    trendWindow = { 'end-1day': 7200,
423
-                    'end-4weeks': 172800,
424
-                    'end-12months': 604800 }
425
- 
426
-    # Format the rrdtool graph command.
427
-
428
-    # Set chart start time, height, and width.
429
-    strCmd = "rrdtool graph %s -a PNG -s %s -e now -w %s -h %s " \
430
-             % (gPath, gStart, _CHART_WIDTH, _CHART_HEIGHT)
431
-   
432
-    # Set the range and scaling of the chart y-axis.
433
-    if lower < upper:
434
-        strCmd  +=  "-l %s -u %s -r " % (lower, upper)
435
-    elif autoScale:
436
-        strCmd += "-A "
437
-    strCmd += "-Y "
438
-
439
-    # Set the chart ordinate label and chart title. 
440
-    strCmd += "-v %s -t %s " % (gLabel, gTitle)
441
- 
442
-    # Show the data, or a moving average trend line over
443
-    # the data, or both.
444
-    strCmd += "DEF:dSeries=%s:%s:LAST " % (_RRD_FILE, dataItem)
445
-    if addTrend == 0:
446
-        strCmd += "LINE1:dSeries#0400ff "
447
-    elif addTrend == 1:
448
-        strCmd += "CDEF:smoothed=dSeries,%s,TREND LINE3:smoothed#ff0000 " \
449
-                  % trendWindow[gStart]
450
-    elif addTrend == 2:
451
-        strCmd += "LINE1:dSeries#0400ff "
452
-        strCmd += "CDEF:smoothed=dSeries,%s,TREND LINE3:smoothed#ff0000 " \
453
-                  % trendWindow[gStart]
454
-     
455
-    if verboseDebug:
456
-        print "%s" % strCmd # DEBUG
457
-    
458
-    # Run the formatted rrdtool command as a subprocess.
459
-    try:
460
-        result = subprocess.check_output(strCmd, \
461
-                     stderr=subprocess.STDOUT,   \
462
-                     shell=True)
463
-    except subprocess.CalledProcessError, exError:
464
-        print "rrdtool graph failed: %s" % (exError.output)
465
-        return False
466
-
467
-    if debugOption:
468
-        print "rrdtool graph: %s\n" % result,
469
-    return True
470
-
471
-##end def
472
-
473
-def generateGraphs():
474
-    """Generate graphs for display in html documents.
475
-       Parameters: none
476
-       Returns: nothing
477
-    """
478
-    autoScale = False
479
-
480
-    # The following will force creation of charts
481
-    # of only signal strength and S/N charts.  Note that the following
482
-    # data items appear constant and do not show variation with time:
483
-    # noise level, rx mcs, rx rate, tx mcs, tx rate.  Therefore, until
484
-    # these parameters are demonstrated to vary in time, there is no point
485
-    # in creating the charts for these data items.
486
-    createAllCharts = False
487
-
488
-    # 24 hour stock charts
489
-
490
-    createGraph('24hr_signal', 'S', 'dBm', 
491
-                'RSSI\ -\ Last\ 24\ Hours', 'end-1day', 0, 0, 2, autoScale)
492
-    createGraph('24hr_snr', 'SNR', 'dB', 
493
-                'SNR\ -\ Last\ 24\ Hours', 'end-1day', 0, 0, 2, autoScale)
494
-
495
-    if createAllCharts:
496
-        createGraph('24hr_noise', 'N', 'dBm', 
497
-                    'Noise\ -\ Last\ 24\ Hours', 'end-1day', 0, 0, 2,
498
-                    autoScale)
499
-        createGraph('24hr_rx_rate', 'RX_RATE', 'Mbps',
500
-                    'Rx\ Rate\ -\ Last\ 24\ Hours', 'end-1day', 0, 0, 2,
501
-                    autoScale)
502
-        createGraph('24hr_tx_rate', 'TX_RATE', 'Mbps',
503
-                    'Tx\ Rate\ -\ Last\ 24\ Hours', 'end-1day', 0, 0, 2,
504
-                    autoScale)
505
-        createGraph('24hr_rx_mcs', 'RX_MCS', 'Index',
506
-                    'Rx\ MCS\ -\ Last\ 24\ Hours', 'end-1day', 0, 0, 2,
507
-                     autoScale)
508
-        createGraph('24hr_tx_mcs', 'TX_MCS', 'Index',
509
-                    'Tx\ MCS\ -\ Last\ 24\ Hours', 'end-1day', 0, 0, 2,
510
-                     autoScale)
511
-
512
-    # 4 week stock charts
513
-
514
-    createGraph('4wk_signal', 'S', 'dBm', 
515
-                'RSSI\ -\ Last\ 4\ Weeks', 'end-4weeks', 0, 0, 2, autoScale)
516
-    createGraph('4wk_snr', 'SNR', 'dB', 
517
-                'SNR\ -\ Last\ 4\ Weeks', 'end-4weeks', 0, 0, 2, autoScale)
518
-
519
-    if createAllCharts:
520
-        createGraph('4wk_noise', 'N', 'dBm', 
521
-                    'Noise\ -\ Last\ 4\ Weeks', 'end-4weeks', 0, 0, 2,
522
-                    autoScale)
523
-        createGraph('4wk_rx_rate', 'RX_RATE', 'Mbps',
524
-                    'Rx\ Rate\ -\ Last\ 4\ Weeks', 'end-4weeks', 0, 0, 2,
525
-                    autoScale)
526
-        createGraph('4wk_tx_rate', 'TX_RATE', 'Mbps',
527
-                    'Tx\ Rate\ -\ Last\ 4\ Weeks', 'end-4weeks', 0, 0, 2,
528
-                    autoScale)
529
-        createGraph('4wk_rx_mcs', 'RX_MCS', 'Index',
530
-                    'Rx\ MCS\ -\ Last\ 4\ Weeks', 'end-4weeks', 0, 0, 2,
531
-                    autoScale)
532
-        createGraph('4wk_tx_mcs', 'TX_MCS', 'Index',
533
-                    'Tx\ MCS\ -\ Last\ 4\ Weeks', 'end-4weeks', 0, 0, 2,
534
-                    autoScale)
535
-
536
-    # 12 month stock charts
537
-
538
-    createGraph('12m_signal', 'S', 'dBm', 
539
-                'RSSI\ -\ Past\ Year', 'end-12months', 0, 0, 2, autoScale)
540
-    createGraph('12m_snr', 'SNR', 'dB', 
541
-                'SNR\ -\ Past\ Year', 'end-12months', 0, 0, 2, autoScale)
542
-
543
-    if createAllCharts:
544
-        createGraph('12m_noise', 'N', 'dBm', 
545
-                    'Noise\ -\ Past\ Year', 'end-12months', 0, 0, 2,
546
-                    autoScale)
547
-        createGraph('12m_rx_rate', 'RX_RATE', 'Mbps',
548
-                    'Rx\ Rate\ -\ Past\ Year', 'end-12months', 0, 0, 2,
549
-                    autoScale)
550
-        createGraph('12m_tx_rate', 'TX_RATE', 'Mbps',
551
-                    'Tx\ Rate\ -\ Past\ Year', 'end-12months', 0, 0, 2,
552
-                    autoScale)
553
-        createGraph('12m_rx_mcs', 'RX_MCS', 'Index',
554
-                    'Rx\ MCS\ -\ Past\ Year', 'end-12months', 0, 0, 2,
555
-                    autoScale)
556
-        createGraph('12m_tx_mcs', 'TX_MCS', 'Index',
557
-                    'Tx\ MCS\ -\ Past\ Year', 'end-12months', 0, 0, 2,
558
-                    autoScale)
559
-    if debugOption:
560
-        #print # print a blank line to improve readability when in debug mode
561
-        pass
562
-##end def
563
-
564
-def getCLarguments():
565
-    """Get command line arguments.  There are four possible arguments
566
-          -d turns on debug mode
567
-          -v turns on verbose debug mode
568
-          -t sets the aredn node query interval
569
-          -u sets the url of the aredn nodeing device
570
-       Returns: nothing
571
-    """
572
-    global debugOption, verboseDebug, dataRequestInterval, \
573
-           arednNodeUrl
574
-
575
-    index = 1
576
-    while index < len(sys.argv):
577
-        if sys.argv[index] == '-d':
578
-            debugOption = True
579
-        elif sys.argv[index] == '-v':
580
-            debugOption = True
581
-            verboseDebug = True
582
-        elif sys.argv[index] == '-p':
583
-            try:
584
-                dataRequestInterval = abs(int(sys.argv[index + 1]))
585
-            except:
586
-                print "invalid polling period"
587
-                exit(-1)
588
-            index += 1
589
-        elif sys.argv[index] == '-u':
590
-            arednNodeUrl = sys.argv[index + 1]
591
-            index += 1
592
-        else:
593
-            cmd_name = sys.argv[0].split('/')
594
-            print "Usage: %s [-d] [-v] [-p seconds] [-u url]" % cmd_name[-1]
595
-            exit(-1)
596
-        index += 1
597
-##end def
598
-
599
-def main():
600
-    """Handles timing of events and acts as executive routine managing
601
-       all other functions.
602
-       Parameters: none
603
-       Returns: nothing
604
-    """
605
-    global dataRequestInterval
606
-
607
-    signal.signal(signal.SIGTERM, terminateAgentProcess)
608
-
609
-    print '%s starting up arednsig agent process' % \
610
-                  (getTimeStamp())
611
-
612
-    # last time output JSON file updated
613
-    lastDataRequestTime = -1
614
-    # last time charts generated
615
-    lastChartUpdateTime = - 1
616
-    # last time the rrdtool database updated
617
-    lastDatabaseUpdateTime = -1
618
-
619
-    ## Get command line arguments.
620
-    getCLarguments()
621
-
622
-    requestIntervalSeconds = dataRequestInterval * 60 # convert to seconds
623
-    chartUpdateInterval = dataRequestInterval # get charts interval
624
-
625
-    ## Exit with error if rrdtool database does not exist.
626
-    if not os.path.exists(_RRD_FILE):
627
-        print 'rrdtool database does not exist\n' \
628
-              'use createArednsigRrd script to ' \
629
-              'create rrdtool database\n'
630
-        exit(1)
631
- 
632
-    ## main loop
633
-    while True:
634
-
635
-        currentTime = time.time() # get current time in seconds
636
-
637
-        # Every web update interval request data from the aredn
638
-        # node and process the received data.
639
-        if currentTime - lastDataRequestTime > requestIntervalSeconds:
640
-            lastDataRequestTime = currentTime
641
-            ldData = []
642
-            result = True
643
-
644
-            # Get the data string from the device.
645
-            sData = getArednNodeData()
646
-            # If the first http request fails, try one more time.
647
-            if sData == None:
648
-                time.sleep(5)
649
-                sData = getArednNodeData()
650
-                if sData == None:
651
-                    result = False
652
-
653
-            # If successful parse the data.
654
-            if result:
655
-                result = parseNodeData(sData, ldData)
656
-           
657
-            # If parsing successful, convert the data.
658
-            if result:
659
-                result = convertData(ldData)
660
-
661
-            # If conversion successful, write data to data files.
662
-            if result:
663
-                result = updateDatabase(ldData)
664
-
665
-            if result:
666
-                writeOutputDataFile(sData, ldData)
667
-
668
-            # Set the node status to online or offline depending on the
669
-            # success or failure of the above operations.
670
-            setNodeStatus(result)
671
-
672
-
673
-        # At the chart generation interval, generate charts.
674
-        if currentTime - lastChartUpdateTime > chartUpdateInterval:
675
-            lastChartUpdateTime = currentTime
676
-            p = multiprocessing.Process(target=generateGraphs, args=())
677
-            p.start()
678
-
679
-        # Relinquish processing back to the operating system until
680
-        # the next update interval.
681
-
682
-        elapsedTime = time.time() - currentTime
683
-        if debugOption:
684
-            if result:
685
-                print "%s update successful:" % getTimeStamp(),
686
-            else:
687
-                print "%s update failed:" % getTimeStamp(),
688
-            print "%6f seconds processing time\n" % elapsedTime 
689
-        remainingTime = requestIntervalSeconds - elapsedTime
690
-        if remainingTime > 0.0:
691
-            time.sleep(remainingTime)
692
-    ## end while
693
-    return
694
-## end def
695
-
696
-if __name__ == '__main__':
697
-    try:
698
-        main()
699
-    except KeyboardInterrupt:
700
-        print '\n',
701
-        terminateAgentProcess('KeyboardInterrupt','Module')
702 0
deleted file mode 100755
... ...
@@ -1,89 +0,0 @@
1
-#!/usr/bin/python -u
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.
4
-#
5
-# Module: createArednsigRrd.py
6
-#
7
-# Description: Creates a rrdtool database for use by the weather agent to
8
-# store the data from the weather station.  The agent uses the data in the
9
-# database to generate graphic charts for display in the weather station
10
-# web page.
11
-#
12
-# Copyright 2020 Jeff Owrey
13
-#    This program is free software: you can redistribute it and/or modify
14
-#    it under the terms of the GNU General Public License as published by
15
-#    the Free Software Foundation, either version 3 of the License, or
16
-#    (at your option) any later version.
17
-#
18
-#    This program is distributed in the hope that it will be useful,
19
-#    but WITHOUT ANY WARRANTY; without even the implied warranty of
20
-#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21
-#    GNU General Public License for more details.
22
-#
23
-#    You should have received a copy of the GNU General Public License
24
-#    along with this program.  If not, see http://www.gnu.org/license.
25
-#
26
-# Revision History
27
-#   * v10 released 11 Jan 2020 by J L Owrey
28
-#
29
-import os
30
-import time
31
-import subprocess
32
-
33
-    ### DEFINE FILE LOCATIONS ###
34
-
35
-_USER = os.environ['USER']
36
-# the file that stores the data
37
-_RRD_FILE = "/home/%s/database/arednsigData.rrd" % _USER
38
-_RRD_SIZE_IN_DAYS = 370 # days
39
-_1YR_RRA_STEPS_PER_DAY = 96
40
-_DATABASE_UPDATE_INTERVAL = 60
41
-
42
-def createRrdFile():
43
-    """Create the rrd file if it does not exist.
44
-       Parameters: none
45
-       Returns: True, if successful
46
-    """
47
-
48
-    if os.path.exists(_RRD_FILE):
49
-        print "aredn node database already exists"
50
-        return True
51
-
52
-     ## Calculate database size
53
- 
54
-    heartBeat = 2 * _DATABASE_UPDATE_INTERVAL
55
-    rra1yrNumPDP =  int(round(86400 / (_1YR_RRA_STEPS_PER_DAY * \
56
-                    _DATABASE_UPDATE_INTERVAL)))
57
-    rrd24hrNumRows = int(round(86400 / _DATABASE_UPDATE_INTERVAL))
58
-    rrd1yearNumRows = _1YR_RRA_STEPS_PER_DAY * _RRD_SIZE_IN_DAYS
59
-       
60
-    strFmt = ("rrdtool create %s --start now-1day --step %s "
61
-              "DS:S:GAUGE:%s:U:U DS:N:GAUGE:%s:U:U DS:SNR:GAUGE:%s:U:U "
62
-              "DS:RX_MCS:GAUGE:%s:U:U DS:TX_MCS:GAUGE:%s:U:U "
63
-              "DS:RX_RATE:GAUGE:%s:U:U DS:TX_RATE:GAUGE:%s:U:U "
64
-              "RRA:LAST:0.5:1:%s RRA:LAST:0.5:%s:%s")
65
-
66
-    strCmd = strFmt % (_RRD_FILE, _DATABASE_UPDATE_INTERVAL, \
67
-                heartBeat, heartBeat, heartBeat, heartBeat,  \
68
-                heartBeat,  heartBeat, heartBeat,            \
69
-                rrd24hrNumRows, rra1yrNumPDP, rrd1yearNumRows)
70
-
71
-    print "creating aredn node database...\n\n%s\n" % strCmd
72
-
73
-    # Spawn a sub-shell and run the command
74
-    try:
75
-        subprocess.check_output(strCmd, stderr=subprocess.STDOUT, \
76
-                                shell=True)
77
-    except subprocess.CalledProcessError, exError:
78
-        print "rrdtool create failed: %s" % (exError.output)
79
-        return False
80
-    return True
81
-##end def
82
-
83
-def main():
84
-    createRrdFile()
85
-## end def
86
-
87
-if __name__ == '__main__':
88
-    main()
89
-        
90 0
deleted file mode 100755
... ...
@@ -1,16 +0,0 @@
1
-#!/bin/sh
2
-#
3
-# Create a directory in the temporary file system for arednsig dynamic
4
-# data.  Set ownership and permissions to allow the Apache www-data user
5
-# read and write access to this folder.
6
-mkdir /tmp/arednsig
7
-sudo chown :www-data /tmp/arednsig
8
-chmod g+w /tmp/arednsig
9
-
10
-# Uncomment the following line if you choose to mount the dynamic
11
-# folder to the folder created above.
12
-#sudo mount --bind /tmp/arednsig  /home/pi/public_html/arednsig/dynamic
13
-
14
-# Start arednsig agent
15
-(sleep 5; /home/pi/bin/ardstart;) &
16
-
17 0
deleted file mode 100644
... ...
@@ -1,323 +0,0 @@
1
-<!DOCTYPE html>
2
-<!-- Courtesy ruler for editing this file
3
-12345678901234567890123456789012345678901234567890123456789012345678901234567890
4
-<html>
5
-<head>
6
-<title>Node Signal</title>
7
-<meta charset="UTF-8">
8
-<meta name="viewport" content="width=device-width, initial-scale=1.0">
9
-<style>
10
-body {
11
-    background-image: url("static/chalk.jpg");
12
-}
13
-h2 {
14
-    font: bold 24px arial, sans-serif;
15
-}
16
-h3 {
17
-    font: bold 18px arial, sans-serif;
18
-}
19
-h4 {
20
-    font: bold 16px arial, sans-serif;
21
-}
22
-.mainContainer {
23
-    width: 750px;
24
-    text-align: center;
25
-    margin: auto;
26
-    /*border: 1px solid black;*/
27
-}
28
-.datetime {
29
-    font: bold 22px arial, sans-serif;
30
-    padding: 0px;
31
-}
32
-.rowContainer {
33
-    display: table;
34
-    width: 100%;
35
-}
36
-.currentDataCell {
37
-    width: 50%;
38
-    padding: 10px;
39
-    font: bold 20px arial, sans-serif;
40
-    text-align: center;
41
-    display: table-cell;
42
-    vertical-align: middle;
43
-}
44
-.dataItems {
45
-    padding: 2px;
46
-    text-align: left;
47
-    line-height: 130%;
48
-    display: inline-block;
49
-    vertical-align: middle;
50
-}
51
-.chartContainer {
52
-    padding: 2px;
53
-}
54
-img.chart {
55
-    width:100%;
56
-}
57
-.notes {
58
-    font: 17px arial, sans-serif;
59
-    text-align: left;
60
-    padding: 10px;
61
-}
62
-span.chartSelector {
63
-    margin: auto;
64
-}
65
-ul.selectorElement {
66
-    list-style-type: none;
67
-    margin: 10px;
68
-    padding: 0;
69
-    overflow: hidden;
70
-    background-color: #bbb;
71
-    text-align: center;
72
-}
73
-li.selectorElement {
74
-    display: inline-block;
75
-    font: bold 18px arial, sans-serif;
76
-    color: black;
77
-}
78
-span.selectorElement:hover {
79
-    background-color: #333;
80
-    cursor: pointer;
81
-    color: white;
82
-}
83
-span.selectorElement {
84
-    display: inline-block;
85
-    padding: 8px 12px;
86
-}
87
-#iframe_a {
88
-    border:none;
89
-    width:100%;
90
-    height:450px;
91
-}
92
-</style>
93
-</head>
94
-
95
-<body onload="main()">
96
-
97
-<div class="mainContainer">
98
-<h2><a href="https://github.com/fractalxaos/ham/tree/master/arednsig" 
99
-  style="text-decoration:none" target="_new">
100
-KA7JLO AREDN<sup>&#174;</sup> Node Signal</a></h2>
101
-<h3>Last Updated</h3>
102
-<div class="datetime">
103
-<span id="date"></span>
104
-&nbsp;&nbsp;
105
-<span id="time"></span>
106
-</div>
107
-
108
-<div class="rowContainer">
109
-<div class="currentDataCell">
110
-<div class="dataItems" style="text-align: center;">
111
-Status: <span id="status"></span><br>
112
-Data updates every: <span id="period"></span> minutes
113
-</div>
114
-
115
-</div>
116
-</div>
117
-
118
-<span class="chartSelectors">
119
-<ul class="selectorElement">
120
-<li class="selectorElement">Select charts:</li>
121
-<li class="selectorElement"><span class="selectorElement"
122
- onclick="setChartPeriod(1)">24 hours</span></li>
123
-<li class="selectorElement"><span class="selectorElement"
124
- onclick="setChartPeriod(2)">4 weeks</span></li>
125
-<li class="selectorElement"><span class="selectorElement"
126
- onclick="setChartPeriod(3)">12 months</span></li>
127
-<li class="selectorElement"><span class="selectorElement"
128
- onclick="setChartPeriod(0)">Custom…</span></li>
129
-</ul>
130
-</span>
131
-
132
-<div class="rowContainer" id="customChartsContainer" style="display:none;">
133
-<div class="currentDataCell">
134
-<form id="fmDateSelector" action="arednsig.php" method="post"
135
- target="iframe_a">
136
-<label for="beginDate">Begin Date: </label>
137
-<input id="beginDate" name="beginDate" type="date" value="mm/dd/yyyy" />
138
-<label for="endDate">End Date: </label>
139
-<input id="endDate" name="endDate" type="date" value="mm/dd/yyyy" />
140
-<br><br>
141
-<input type="button" onclick="getCustomCharts()" value="Get Charts">
142
-</form>
143
-<span id="errorMsg"></span><br>
144
-<iframe id="iframe_a" name="iframe_a"></iframe>
145
-</div>
146
-</div>
147
-
148
-<br>
149
-
150
-<div class="rowContainer" id="stockChartsContainer">
151
-<div class="chartContainer">
152
-<img class="chart" id="signalChart">
153
-</div>
154
-<div class="chartContainer">
155
-<img class="chart" id="snrChart">
156
-</div>
157
-</div>
158
-
159
-<div class="notes">
160
-<b>NOTES:</b>
161
-<ul>
162
-<li>Aredn Node Signal software available at
163
-<a href="https://github.com/fractalxaos/ham/tree/master/arednsig"
164
- target="_new">
165
-<i>Github.com</i></a>.</li>
166
-<li>Project sponsored by 
167
-<a href="https://willamettevalleymesh.net" TARGET="_NEW">
168
-<i>Willamette Valley Mesh Network</i></a>, Salem, Oregon.</li>
169
-<li>For more information about the amateur radio emergency
170
- data network (AREDN) see official web site at
171
- <a href="http://www.arednmesh.org" target="_blank">
172
-www.arednmesh.org</a>.</li>
173
-</ul>
174
-</div>
175
-</div>
176
-<br>
177
-
178
-<script>
179
-
180
-/* Global constants */
181
-
182
-var nodeDataUrl = "dynamic/nodeOnline.js";
183
-
184
-/* Global DOM objects */
185
-
186
-// Chart elements
187
-var signalChart = document.getElementById("signalChart");
188
-var snrChart = document.getElementById("snrChart");
189
-
190
-// Text elements
191
-var dateElmt = document.getElementById("date");    
192
-var timeElmt = document.getElementById("time"); 
193
-var statusElmt = document.getElementById("status");
194
-var periodElmt = document.getElementById("period");
195
-
196
-// Document elements
197
-var customChartsContainer = document.getElementById("customChartsContainer");
198
-var stockChartsContainer = document.getElementById("stockChartsContainer");
199
-var fmDateSelector = document.getElementById("fmDateSelector");
200
-var errorMsg = document.getElementById("errorMsg");
201
-
202
-/* Global objects */
203
-
204
-var httpRequest = new XMLHttpRequest();
205
-
206
-/* Global variables */
207
-
208
-var chartPeriod = 1;
209
-var chartRefreshRate = 0; // chart refresh rate in minutes
210
-
211
-function main() {
212
-    /* Register call back function to process http requests */
213
-    httpRequest.onreadystatechange = function() {
214
-        if (httpRequest.readyState == 4 && httpRequest.status == 200) {
215
-            var dataArray = JSON.parse(httpRequest.responseText);
216
-            displayData(dataArray[0]);
217
-        } else if (httpRequest.readyState == 4 && httpRequest.status == 404) {
218
-            displayOfflineStatus();
219
-        }
220
-    };
221
-    httpRequest.ontimeout = function(e) {
222
-        displayOfflineStatus();
223
-    };
224
-
225
-    initializeDateSelector();
226
-    getNodeData();
227
-    getNodeCharts();
228
-}
229
-
230
-function getNodeData() {
231
-    httpRequest.open("GET", nodeDataUrl, true);
232
-    httpRequest.timeout = 3000;
233
-    httpRequest.send();
234
-}
235
-
236
-function setChartPeriod(n) {
237
-    chartPeriod = n;
238
-    if (n == 0) {
239
-        customChartsContainer.style.display = "block";
240
-        stockChartsContainer.style.display = "none";
241
-    } else {
242
-        customChartsContainer.style.display = "none";
243
-        stockChartsContainer.style.display = "block";
244
-    getNodeCharts();   
245
-    }
246
-}
247
-
248
-function getNodeCharts() {
249
-    var d = new Date;
250
-    var pfx;
251
-
252
-    switch(chartPeriod) {
253
-        case 1:
254
-            pfx = "24hr_";
255
-            break;
256
-        case 2:
257
-            pfx = "4wk_";
258
-            break;
259
-       case 3:
260
-            pfx = "12m_";
261
-            break;
262
-    }
263
-    signalChart.src = "dynamic/" + pfx + "signal.png?ver=" + d.getTime();
264
-    snrChart.src = "dynamic/" + pfx + "snr.png?ver=" + d.getTime();
265
-}
266
-
267
-function displayData(dataItem) {
268
-    var timeStamp, date, time, hourminute;
269
-    var localDateObj,localTimeZone;
270
-
271
-    timeStamp = dataItem.date;
272
-    date = timeStamp.split(" ")[0];
273
-    time = timeStamp.split(" ")[1];
274
-    hourminute = time.split(":")[0] + ":" + time.split(":")[1];
275
-    localDate = new Date();
276
-    localTimeZone = localDate.getTimezoneOffset() / 60;
277
-    dateElmt.innerHTML = date;    
278
-    timeElmt.innerHTML = hourminute +
279
-                         "  <small>(GMT+" + localTimeZone + ")</small>";    
280
-     
281
-    statusElmt.innerHTML = "Online";
282
-    statusElmt.style.color = "green";
283
-
284
-    chartRefreshRate = dataItem.period;
285
-    periodElmt.innerHTML = chartRefreshRate;
286
-    setInterval(getNodeData, 60000 * chartRefreshRate);
287
-    setInterval(getNodeCharts, 60000 * chartRefreshRate);
288
-}
289
-
290
-function displayOfflineStatus() {
291
-    var d = new Date();
292
-    localTimeZone = d.getTimezoneOffset() / 60;
293
-    dateElmt.innerHTML = (d.getMonth() + 1) + "/" + d.getDate() + "/" +
294
-                          d.getFullYear();    
295
-    timeElmt.innerHTML = d.getHours() + ":" + d.getMinutes() +
296
-                         "  <small>(GMT+" + localTimeZone + ")</small>";
297
-    periodElmt.innerHTML = "?";    
298
-    statusElmt.innerHTML = "offline";    
299
-    statusElmt.style.color = "red";
300
-}
301
-
302
-function initializeDateSelector() {
303
-    var d = new Date();
304
-
305
-    var dEnd = new Date(d.getFullYear(),
306
-               d.getMonth(), d.getDate() - 0);
307
-
308
-    var dBegin = new Date(d.getFullYear(),
309
-               d.getMonth(), d.getDate() - 1);
310
-
311
-    document.getElementById("beginDate").valueAsDate = dBegin;
312
-    document.getElementById("endDate").valueAsDate = dEnd;
313
-}
314
-
315
-function getCustomCharts() {
316
-    fmDateSelector.submit();
317
-}
318
-</script>
319
-
320
-</body>
321
-</html>
322
-
323 0
deleted file mode 100644
... ...
@@ -1,205 +0,0 @@
1
-<html>
2
-<!-- Courtsey ruler
3
-12345678901234567890123456789012345678901234567890123456789012345678901234567890
4
-<head>
5
-<style>
6
-p {
7
-    font: 14px ariel, sans serif;
8
-}
9
-#errorMsg {
10
-    font:bold 18px arial,sans-serif;
11
-    color:red;
12
-    text-align:center;
13
-}
14
-.chartContainer {
15
-    padding: 2px;
16
-}
17
-img.chart {
18
-    width:100%;
19
-}
20
-</style>
21
-</head>
22
-<body>
23
-
24
-<?php
25
-/*
26
- Script: arednsig.php
27
-
28
- Description: This scripts generates on the server charts showing
29
- signal data spanning the period supplied by the user.  The script
30
- does the following:
31
-    - converts user supplied dates to  epoch time
32
-    - gets the times of the first and last data point in the round
33
-      robin database (RRD)
34
-    - from above validates user supplied begin and end dates
35
-    - creates charts of the specified period
36
-
37
- Copyright 2020 Jeff Owrey
38
-    This program is free software: you can redistribute it and/or modify
39
-    it under the terms of the GNU General Public License as published by
40
-    the Free Software Foundation, either version 3 of the License, or
41
-    (at your option) any later version.
42
-
43
-    This program is distributed in the hope that it will be useful,
44
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
45
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
46
-    GNU General Public License for more details.
47
-
48
-    You should have received a copy of the GNU General Public License
49
-    along with this program.  If not, see http://www.gnu.org/license.
50
-
51
- Revision History
52
-   * v20 released 18 Jan 2020 by J L Owrey; first release
53
-*/
54
-
55
-# Define global constants
56
-
57
-# round robin database file
58
-define("_RRD_FILE", str_replace("public_html/arednsig/arednsig.php",
59
-                                "database/arednsigData.rrd",
60
-                                $_SERVER["SCRIPT_FILENAME"]));
61
-# charts html directory
62
-define("_CHART_DIRECTORY", str_replace("arednsig.php",
63
-                                       "dynamic/",
64
-                                       $_SERVER["SCRIPT_FILENAME"]));
65
-# standard chart width in pixels
66
-define("_CHART_WIDTH", 600);
67
-# standard chart height in pixels
68
-define("_CHART_HEIGHT", 150);
69
-# debug mode
70
-define("_DEBUG", false);
71
-
72
-# Set error handling modes.
73
-error_reporting(E_ALL);
74
-
75
-# Get user supplied chart begin and end dates.
76
-$beginDate = $_POST["beginDate"];
77
-$endDate =  $_POST["endDate"];
78
-
79
-# Convert the user supplied dates to epoch time stamps.
80
-$beginDateEp = strtotime($beginDate);
81
-$endDateEp = strtotime($endDate);
82
-
83
-# Get the time stamp of the earliest data point in the RRD file.
84
-$cmd = sprintf("rrdtool first %s --rraindex 1", _RRD_FILE);
85
-$firstDP = shell_exec($cmd);
86
-
87
-# Get the time stamp of the latest data point in the RRD file.
88
-$cmd = sprintf("rrdtool last %s", _RRD_FILE);
89
-$lastDP = shell_exec($cmd);
90
-
91
-# Determine validity of user supplied dates.  User supplied begin
92
-# date must be less than user supplied end date.  Furthermore both
93
-# dates must be within the range of dates stored in the RRD.
94
-if ($beginDateEp > $endDateEp) {
95
-    echo "<p id=\"errorMsg\">" .
96
-         "End date must be after begin date.</p>";
97
-} elseif ($beginDateEp < $firstDP || $endDateEp > $lastDP) {
98
-    echo "<p id=\"errorMsg\">" .
99
-          "Date range must be between " .
100
-          date('m / d / Y', $firstDP) . " and " . 
101
-          date('m / d / Y', $lastDP) . ".</p>";
102
-} else {
103
-    # Generate charts from validated user supplied dates.
104
-    if (_DEBUG) {
105
-        echo "<p>Date range: " . $beginDateEp . " thru " .
106
-              $endDateEp . "</p>";
107
-    }
108
-    createChart('custom_signal', 'S', 'dBm', 
109
-                'RSSI', $beginDateEp, $endDateEp,
110
-                 0, 0, 2, false);
111
-    createChart('custom_snr', 'SNR', 'dBm', 
112
-                'S/N', $beginDateEp, $endDateEp,
113
-                 0, 0, 2, false);
114
-    # Send html commands to client browser.
115
-    echo "<div class=\"chartContainer\">" .
116
-         "<img class=\"chart\" src=\"dynamic/custom_signal.png\">" .
117
-         "</div>";
118
-    echo "<div class=\"chartContainer\">" .
119
-         "<img class=\"chart\" src=\"dynamic/custom_snr.png\">" .
120
-         "</div>";
121
-}
122
-
123
-function createChart($chartFile, $dataItem, $label, $title, $begin,
124
-                     $end, $lower, $upper, $addTrend, $autoScale) {
125
-    /*
126
-    Uses rrdtool to create a chart of specified aredn node data item.
127
-    Parameters:
128
-       fileName - name of the created chart file
129
-       dataItem - data item to be charted
130
-       label - string containing a label for the item to be charted
131
-       title - string containing a title for the chart
132
-       begin - beginning time of the chart data
133
-       end   - ending time of the data to be charted
134
-       lower - lower bound for chart ordinate #NOT USED
135
-       upper - upper bound for chart ordinate #NOT USED
136
-       addTrend - 0, show only chart data
137
-                  1, show only a trend line
138
-                  2, show a trend line and the chart data
139
-       autoScale - if True, then use vertical axis auto scaling
140
-           (lower and upper parameters are ignored), otherwise use
141
-           lower and upper parameters to set vertical axis scale
142
-    Returns: True if successful, False otherwise
143
-    */
144
-
145
-    # Define path on server to chart files.
146
-    $chartPath = _CHART_DIRECTORY . $chartFile . ".png";
147
-
148
-    # Format the rrdtool chart command.
149
-
150
-    # Set chart file name, start time, end time, height, and width.
151
-    $cmdfmt = "rrdtool graph %s -a PNG -s %s -e %s -w %s -h %s ";
152
-    $cmd = sprintf($cmdfmt, $chartPath, $begin, $end, _CHART_WIDTH,
153
-                   _CHART_HEIGHT);
154
-    $cmdfmt = "-l %s -u %s -r ";
155
-
156
-    # Set upper and lower ordinate bounds.
157
-    if ($lower < $upper) {
158
-        $cmd .= sprintf($cmdfmt, $lower, $upper);
159
-    } elseif ($autoScale) {
160
-        $cmd .= "-A ";
161
-    }
162
-    $cmd .= "-Y ";
163
-
164
-    # Set the chart ordinate label and chart title. 
165
-    $cmdfmt = "-v %s -t %s ";
166
-    $cmd .= sprintf($cmdfmt, $label, $title);
167
-   
168
-    # Define moving average window width.
169
-    $trendWindow = floor(($end - $begin) / 12);
170
-        
171
-    # Show the data, or a moving average trend line over
172
-    # the data, or both.
173
-    $cmdfmt = "DEF:dSeries=%s:%s:LAST ";
174
-    $cmd .= sprintf($cmdfmt, _RRD_FILE, $dataItem);
175
-    if ($addTrend == 0) {
176
-        $cmd .= "LINE1:dSeries#0400ff ";
177
-    } elseif ($addTrend == 1) {
178
-        $cmdfmt = "CDEF:smoothed=dSeries,%s,TREND LINE3:smoothed#ff0000 ";
179
-        $cmd .= sprintf($cmdfmt, $trendWindow);
180
-    } elseif ($addTrend == 2) {
181
-        $cmd .= "LINE1:dSeries#0400ff ";
182
-        $cmdfmt = "CDEF:smoothed=dSeries,%s,TREND LINE3:smoothed#ff0000 ";
183
-        #$cmdfmt = "CDEF:smoothed=dSeries,%s,XYZZY LINE3:smoothed#ff0000 ";
184
-        $cmd .=  sprintf($cmdfmt, $trendWindow);
185
-    }
186
-     
187
-    # Execute the formatted rrdtool command in the shell. The rrdtool
188
-    # command will complete execution before the html image tags get
189
-    # sent to the browser.  This assures that the charts are available
190
-    # when the client browser executes the html code that loads the
191
-    # charts into the document displayed by the client browser.
192
-    if (_DEBUG) {
193
-        echo "<p>chart command:<br>" . $cmd . "</p>";
194
-    }
195
-    $result = shell_exec($cmd . " 2>&1");
196
-    if (_DEBUG) {
197
-        echo "<p>result:<br>" . $result . "</p>";
198
-    }
199
-}
200
-
201
-?>
202
-
203
-</body>
204
-</html>
205 0
deleted file mode 100644
... ...
@@ -1,7 +0,0 @@
1
-<!DOCTYPE html>
2
-<html>
3
-<head>
4
-  <meta http-equiv="refresh" content="0; url=./arednsig.html">
5
-  <!--<meta http-equiv="refresh" content="0; url=https://github.com/fractalxaos/radmon">-->
6
-</head>
7
-</html>
8 0
deleted file mode 100644
9 1
Binary files a/arednsig/aredn_fw_3_19_3_0/html/static/chalk.jpg and /dev/null differ