/*-
 * Copyright (c) 1998-2003 Poul-Henning Kamp
 *
 * Please see src/share/examples/etc/bsd-style-copyright.
 *
 */

#include <sys/cdefs.h>

#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <err.h>
#include <sys/timepps.h>

int
main(int argc, char **argv)
{
	int fd;
	pps_info_t pi;
	pps_params_t pp;
	pps_handle_t ph;
	int i;
	u_int olda, c;
	struct timespec to;
	double d, dl, dt, p, dp, sp;

	argc -= 1;
	argv += 1;

	/* use given devicename or stdin */

	if (argc > 0) {
		fd = open(argv[0], O_RDONLY);
		if (fd < 0) 
			err(1, argv[0]);
	} else {
		fd = 0;
	}

	/* Setup PPS-API to catch raising flanks */
	i = time_pps_create(fd, &ph);
	if (i < 0)
		err(1, "time_pps_create");

	i = time_pps_getparams(ph, &pp);
	if (i < 0)
		err(1, "time_pps_getparams():");

	pp.mode |= PPS_CAPTUREASSERT;

	if (!(pp.mode & PPS_TSFMT_TSPEC))
		pp.mode |= PPS_TSFMT_TSPEC;
	
	i = time_pps_setparams(ph, &pp);
	if (i < 0) {
		err(1, "time_pps_setparams(mode %x):", pp.mode);
	}

	/*
	 * Pick up first event outside the loop in order to not
	 * get something ancient into the outfile.
	 */
	to.tv_nsec = 0;
	to.tv_sec = 0;
	i = time_pps_fetch(ph, PPS_TSFMT_TSPEC, &pi, &to);
	if (i < 0)
		err(1, "time_pps_fetch()");
	olda = pi.assert_sequence;
	dl = pi.assert_timestamp.tv_sec +
	     pi.assert_timestamp.tv_nsec * 1e-9;

	sp = 0;
	printf("%18s %12s %6s %8s %8s %6s\n",
	    "Time", "dT", "pulses", "kW", "kWh", "DKR");
	while (1) {
		to.tv_nsec = 0;
		to.tv_sec = 0;
		i = time_pps_fetch(ph, PPS_TSFMT_TSPEC, &pi, &to);
		if (i < 0)
			err(1, "time_pps_fetch()");

		/* If no event yet, wait a little while, then try again */
		if (olda == pi.assert_sequence) {
			usleep(10000);
			continue;
		}


		d = pi.assert_timestamp.tv_sec +
		     pi.assert_timestamp.tv_nsec * 1e-9;
		dt = d - dl;

		c = pi.assert_sequence - olda;

		/* 10000 pulses per kWh */
		dp = c / 10000.0;

		/* 10000 pulses per kWh, 3600 second per hour */
		p = dp / (dt / 3600.0);
		sp += dp;

		printf("%18.3f %12.9f %6u %8.4f %8.4f %6.2f\n",
		    d, dt, c, p, sp, sp * 1.738);
		sleep(1);
			
		dl = d;
		olda = pi.assert_sequence;
	}
	return(0);
}
