#!/bin/sh

# Script to generate CSV and graph of load profile based on Enphase data.
# Can be compared with, eg, standard Elexon GB profile classes.
# Shows both gross consumption as if PV and battery not there, and net.

# Enphase 'monthly net energy' data format is in 15-minute blocks such as:
#Date/Time,Energy Produced (Wh),Energy Consumed (Wh),Exported to Grid (Wh),Imported from Grid (Wh),Stored in AC Batteries (Wh),Discharged from AC Batteries (Wh)
#2020-12-01 00:00:00 +0000,0,14,0,15,1,0
#2020-12-01 00:15:00 +0000,0,25,0,26,1,0
#2020-12-01 00:30:00 +0000,0,16,0,17,1,0
#2020-12-01 00:45:00 +0000,0,15,0,16,1,0
#2020-12-01 01:00:00 +0000,0,29,0,30,1,0
#2020-12-01 01:15:00 +0000,0,28,0,29,1,0
#2020-12-01 01:30:00 +0000,0,59,0,60,1,0
#2020-12-01 01:45:00 +0000,0,51,0,52,1,0
#2020-12-01 02:00:00 +0000,0,27,0,28,1,0

# Output gnuplot graphing script.
GPSCRIPT=graphing/storesim/load-profile-1.txt
if [ ! -s "${GPSCRIPT}" ]; then
    echo ERROR: missing gnuplot script "${GPSCRIPT}". 1>&2
    exit 1
fi

# Output directory.
# Intended to be a working area only, to be moved somewhere under img.
OUTDIR=$HOME/tmp/load-profile
if [ ! -d "${OUTDIR}" ]; then
    echo ERROR: missing output directory "${OUTDIR}". 1>&2
    exit 1
fi

# Location of data files:
#DATADIR=data/16WWHiRes/Enphase/adhoc
DATADIR=$HOME/tmp/
# Default, gzipped, data sources:
#DATASOURCES="202006 202008 202009 202010 202011 202012-01to21"
#DATASOURCES="202006 202012-01to21"
DATASOURCES="202011 202111"

# Default set of filters to use from: all, week, weekend
FILTERS="all weekday weekend"

for datasource in $DATASOURCES;
    do
    DATASOURCEGZ=$DATADIR/net_energy_${datasource}.csv.gz
    if [ ! -s "${DATASOURCEGZ}" ]; then
        echo ERROR: missing data source "${DATASOURCEGZ}". 1>&2
        exit 1
    fi

    # Uncompress, filter, batch, and create a .csv and .png file.
    # The CSV file is directly usable and also feeds gnuplot for graphing.
    for filter in $FILTERS;
        do

        # Generate a simple CSV file.
        # The CSV content may look like:
        #00:00:00,21,67,71
        #00:15:00,21,77,81
        #00:30:00,21,61,65
        #00:45:00,21,73,77
        #01:00:00,21,84,88
        #01:15:00,21,69,73
        #01:30:00,21,72,76
        #01:45:00,21,81,85
        #02:00:00,21,71,75
        OUTCSV=$OUTDIR/bucketed.$datasource.$filter.csv
        # Output in mean (rounded) watts:
        #     time-of-day,count,mean-gross-W,mean-net-W
        # eg:
        #00:00:00,14,15
        #00:15:00,25,26
        #00:30:00,16,17
        rm -f $OUTCSV.tmp

        #filtercmd="cat"
        #case $filter in
        #    all) filtercmd="cat";;
        #    weekend) ;;
        #    *) echo ERROR: bad "${filter}". 1>&2; exit 1;;
        #esac

echo "$filter" "$filtercmd"

        gzip -d < "$DATASOURCEGZ" |

            # Set up data filter ahead of processing.
            case $filter in
                all) cat;;
                weekday) perl -lF/,/ -MPOSIX -e 'my ($year, $month, $day) = $F[0] =~ m/(\d{4})-(\d{2})-(\d{2})/; if(POSIX::strftime("%u", 0, 0, 0, $day, $month - 1, $year - 1900) <= 5) { print }';;
                weekend) perl -lF/,/ -MPOSIX -e 'my ($year, $month, $day) = $F[0] =~ m/(\d{4})-(\d{2})-(\d{2})/; if(POSIX::strftime("%u", 0, 0, 0, $day, $month - 1, $year - 1900) > 5) { print }';;
                *) echo ERROR: bad filter "${filter}". 1>&2; exit 1;;
            esac |

            awk -F, '
                $1 ~ /^202/ {
                date=substr($1,12,8);
                ++count[date];
                # Buckets are assumed to be 15 mins, so W = 4*Wh.
                gross[date] += 4 * $3;
                net[date] += 4 * ($5-$4);
                }
            END { 
                for(date in count) {
                    n = count[date];
                    print date "," n "," int(gross[date]/n+0.5) "," int(net[date]/n+0.5);
                    }
                }' | sort > $OUTCSV.tmp
        if [ -s $OUTCSV.tmp ]; then
            mv -f $OUTCSV.tmp $OUTCSV
            chmod a+r $OUTCSV
            echo Created bucketed CSV filtered ${filter}: $OUTCSV
        fi

        # Generate a simple .png chart.
        OUTPNG=$OUTDIR/bucketed.$datasource.$filter.png
        rm -f ${OUTPNG}.tmp
        gnuplot -e "title='Load Profile: ${datasource} ${filter}'" \
            -e "infilename='${OUTCSV}'" -e "outfilename='${OUTPNG}.tmp'" \
            ${GPSCRIPT}
        if [ -s $OUTPNG.tmp ]; then
            mv -f $OUTPNG.tmp $OUTPNG
            chmod a+r $OUTPNG
            echo Created bucketed PNG filtered ${filter}: $OUTPNG
        fi

        done # filter

    done # datasource



# weekend) filtercmd="perl -lF/,/ -MPOSIX -e 'my (\$year, \$month, \$day) = \$F[0] =~ m/(\d{4})-(\d{2})-(\d{2})/; if(POSIX::strftime(\"%u\", 0, 0, 0, \$day, \$month - 1, \$year - 1900) > 5) { print }' " ;;
# perl < tmp/testdata.dat -l'F/,/' -MPOSIX -e 'my ($year, $month, $day) = $F[0] =~ m/(\d{4})-(\d{2})-(\d{2})/; print POSIX::strftime("%u", 0, 0, 0, $day, $month - 1, $year - 1900);'
