  The files from the client (upshost) and the server (server) below are used to transfer the UPS voltage from upshost to server via ssh. They are contained in the following:

.
├── server
│   └── usr
│       └── local
│           └── bin
│               └── apclinev
└── upshost
    ├── etc
    │   └── systemd
    │       └── system
    │           ├── apcaccess-linev.service
    │           └── apcaccess-linev.timer
    └── usr
        └── local
            └── bin
                └── apcaccess-log-linev-timer.sh


  The systemd timer runs ever 10 minutes and invokes the apcaccess-log-linev-timer.sh script. You can replace the entire systemd timer with a simple cron job of '*/10 * * * * /usr/local/bin/apcaccess-log-linev-timer.sh 2>&1' which does the same thing. cron is the old way to do things, simpler, quicker. A systemd timer takes creating both the .service and .timer files and then starting/enabling the timer, e.g.

  systemctl start apcaccess-linev.timer
  systemctl enable apcaccess-linev.timer

  For cron, you simply need to add the cron entry with `crontab -e` and then paste the entry above.

  The entire script, 'apcaccess-log-linev-timer.sh' is simply a command substitution that uses date for the date/time and awk to grab the line voltage from the output of 'apcaccess' the utility provided by the apcupsd package that monitors the APC UPS on the host. The script is:

#!/bin/sh

## NOTE: above is POSIX shell, not bash

## save date/time,voltage entry transfer to server via ssh
entry="$(apcaccess | awk -v dt="$(date +'%m/%d/%Y %H:%M')" '$1 == "LINEV" { printf "%s,%s\n", dt, $3; exit }')"

## pipe entry over ssh to server to be read by apclinev script in /usr/local/bin
printf '%s\n' "$entry" | ssh david@valkyrie 'apclinev'

  Note when writing system control scripts, you ideally want to use POSIX shell/ash/dash, not an advanced shell like bash, ksh, or zsh, just so what you write is compatable with any system, not just one that happens to have your advanced shell on it.

  Everything in "$(...)" is the command substitution that uses awk and date to grab the date and add the line voltage to it separated by a comma. The last printf command just pipes that text to the server via ssh where it is read by the 'abclinev' script invoked by the ssh command:

#!/bin/sh

cleanup() {
  bzip2 "$logfn"                # bzip logfile
}

logdir=/srv/http/tmp/data       # log dir
logfn="$logdir"/apclinev.log    # log filename
bzfn="$logfn".bz2               # compressed log filename

test -w "$bzfn" && bzip2 -d "$bzfn"   # unzip if bz2 exists

## set trap to bzip2 logfile and handle fd restore and close
trap cleanup TERM INT EXIT

## write stdin to logfile
cat - >>"$logfn"

  Above the cleanup() function is called by trap (a specific shell feature) that run when any of the signals TERM, INT or EXIT is received by the script. So the script simply unzips the log file (if a zipped log file exists), sets the trap, and then uses 'cat -` (cat stdin) redirected to the logfile.

  That's it, you can scape the page and get the rest. The log files are in /srv/http/tmp/data along with the C file parseupsbz2.c which reads the bzipped logs and gets current, avg, min, max from it. 

  The layers of learning in this little page are like an onion, you can just keep peeling back the layers to find more good stuff inside. Above is just the data handling, how the data gets from the host to the server and is stored in the most efficient manner. The html, css, js and php are also this level deep in learning.

  Look it over and let me know if you have questions.
