#!/bin/sh
# Extract sensor (eg temperature) trace from stdin and convert to raw audio.
# This converts to a constant-sample-rate binary WAVE (.wav) file on stdout.
# This file can be further processed (eg to adjust its timebase, normalise).
#
# Usage:
#     $0 < JSON.data [FIELD [SENSOR [SAMPLETICKS [OUTPUTSAMPLEFREQ]]]]
#
# Where:
#     FIELD is the JSON field name, eg "O" or "T|16", quoted for safety.
#     SENSOR is the sensor unique ID.
#     SAMPLETICKS is the number of UTC seconds per audio sample.
#     OUTPUTSAMPLEFREQ is the nominal WAV audio sample frequency.
#
# Several procesisng passes may be required because of details of the
# file formats, etc.

##########
# May be used / adapted / etc without any promise of fitness for purpose
# under the terms of the Apache License Version 2.0, January 2004
#     http://www.apache.org/licenses/LICENSE-2.0
##########

# FIXME: Default values are provided for now...
# "T|C16" is temperature in 1/16 degrees Celsius.
FIELD="T|C16"
# Sensor E091B7DC8FEDC7A9 is 5s, 819C99B4B9BD84BB is 4o.
SENSOR="E091B7DC8FEDC7A9"
# Default target output sample frequency (Hz).
OUTPUTSAMPLEFREQ=44100
# 1 year = 31536000s = 525600 minutes.  (Temp sampling is once per minute.)
# One sample per 715s compresses 1 year to ~1s at 44100Hz nominal sample rate.
SAMPLETICKS=715

if [ "$#" -gt 0 ]; then
    FIELD="$1"
    shift
    echo "INFO: FIELD=$FIELD" 1>&2
fi

if [ "$#" -gt 0 ]; then
    SENSOR="$1"
    shift
    echo "INFO: SENSOR=$SENSOR" 1>&2
fi

if [ "$#" -gt 0 ]; then
    SAMPLETICKS="$1"
    shift
    echo "INFO: SAMPLETICKS=$SAMPLETICKS" 1>&2
fi

if [ "$#" -gt 0 ]; then
    OUTPUTSAMPLEFREQ="$1"
    shift
    echo "INFO: OUTPUTSAMPLEFREQ=$OUTPUTSAMPLEFREQ" 1>&2
fi

# This first extracts the samples from the input OpenTRV stats JSON file
# for the given sensor and parameter, in format:
# [ "2019-08-01T00:00:00Z", "", {"@":"95ABDC89C1999C9E","+":7,"tT|C":11,"tS|C":6} ]
# [ "2019-08-01T00:00:07Z", "", {"@":"FEDA88A08188E083","+":11,"O":1,"vac|h":15,"B |cV":304} ]
# [ "2019-08-01T00:00:21Z", "", {"@":"FA97A8A7B7D2D3B6","+":1,"R":4,"err":0,"T|C16 ":359} ]
# [ "2019-08-01T00:00:37Z", "", {"@":"84F3D6D893A3F2E0","+":0,"T|C16":458,"b":1,"R ":108} ]
#
# Eg, extracting temperature traces for 5s (E091B7DC8FEDC7A9) may look like:
#gzip -d < data/OpenTRV/pubarchive/remote/201908.json.gz | sh OpenTRV/scripts/filterJSON.sh "T|C16" E091B7DC8FEDC7A9
# 2019-08-01T00:02:44Z E091B7DC8FEDC7A9 348
# 2019-08-01T00:10:54Z E091B7DC8FEDC7A9 347
# 2019-08-01T00:18:58Z E091B7DC8FEDC7A9 346
# 2019-08-01T00:20:46Z E091B7DC8FEDC7A9 346
#
# 4o (outside) is 819C99B4B9BD84BB.


# Base name for any temporary files created by instances of this script.
# Note trailing / on TMPDIR for systems such as macOS where /tmp is a symlink.
TMPDIR=/tmp/
TMPCONV=.tempYear1s
TMPBASE=$TMPDIR.tmp$TMPCONV
# Base name for any temporary files created by this instance.
# Use as $TMPBASETHIS.XXX
TMPBASETHIS=$TMPBASE.$$
# Trap unexpected exits with tidyup.
trap "/bin/rm -f ${TMPBASETHIS}.*; exit 1" 1 2 15
# In background remove any very old temp files.
#find $TMPDIR/ -maxdepth 1 -name .tmp$TMPCONV'*' -mtime +1 -exec rm -f {} \; >/dev/null 2>&1 &

# All working times are in UTC to avoid DST time shifts!
TZ=UTC
export TZ

# Read from stdin, filter, resample to constant time base.
# Output one (signed 16-bit) sample value per SAMPLETICKS.
# The last value seen at or before the tick is output.
# Intermediate output values are inserted where inputs have a wider gap.
TMPRESAMPLED=${TMPBASETHIS}.resampled.txt
OpenTRV/scripts/filterJSON "$FIELD" "$SENSOR" | \
    awk -v SAMPLETICKS=$SAMPLETICKS '
         BEGIN { nextO=0; }
         {
         # T is ISO 8601 format UTC time (eg "2019-08-01T00:02:44Z").
         # s is seconds since the system epoch.
         T=$1; gsub(/[-:TZ]/, " ", T); s=mktime(T);
         if(start<1) { start=s; } # Capture first sample time (epoch seconds).
         adjS = s - start;
         # Capture the current sample value.
         currSampleT = adjS;
         currSampleI = $3;
         #print " (In:", $3, "@", adjS ")"; #DEBUG
         # Output zero or more repeats of the last input sample.
         while(adjS >= nextO) {
             sampleO = ((adjS==nextO)?currSampleI:prevSampleI);
             # Print output sample as value on own line.
             print sampleO;
             nextO += SAMPLETICKS;
             }
         # Remember as the previous input sample.
         prevSampleT = adjS;
         prevSampleI = $3;
         }' > $TMPRESAMPLED
# Output is one number per line per sample (eg at 44100Hz), eg:
# % head $TMPRESAMPLED
# 348
# 347
# 346
# 345
# 344
# 343
# 343
# 341
# 340
# 339

#OUTPUTSAMPLES=`wc -l < $TMPRESAMPLED`
#echo "INFO: resampled output count: $OUTPUTSAMPLES" 1>&2

# Convert to raw WAV on stdout.
script/mkaudio/textToWAV $TMPRESAMPLED $OUTPUTSAMPLEFREQ

# Clear up temp data.
/bin/rm -f ${TMPBASETHIS}.*

exit 0
