#if 0
    INDI
    Copyright (C) 2003 Elwood C. Downey

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
    License as published by the Free Software Foundation; either
    version 2.1 of the License, or (at your option) any later version.

    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public
    License along with this library; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

#endif

/* simulate a weather station with several passive instruments.
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include <math.h>
#include <sys/time.h>
#include <unistd.h>

#include "astro.h"
#include "indidevapi.h"

static void sendWX (void);
static void wxSim (void *p);


#define	POLLMS		987			/* poll period, ms */

/* operational info */
#define MYDEV "Weather"		/* Device name we call ourselves */

static IPState ds = IPS_OK;	/* dew point state */
static IPState ss = IPS_OK;	/* wind speed state */

/* weather information */
static INumber wx[] = {
    {"Pres", "Pressure, hPa",   "%6.1f", 0,0,0, 1000},
    {"Temp", "Air temp, C",     "%6.1f", 0,0,0, 10},
    {"DewP", "Dew point, C",    "%6.1f", 0,0,0, 6},
    {"WDir", "Wind dir, EofN",  "%6.1f", 0,0,0, 90},
    {"WSpd", "Wind speed, kph", "%6.1f", 0,0,0, 22},
};
typedef enum {
    PRES, TEMP, DEWP, WDIR, WSPD
} WXIndex;
static INumberVectorProperty wxNum = {MYDEV, "WX", "Weather Station", "",
   IP_RO, 0, IPS_OK, wx, NARRAY(wx)};

/* weather safe limits */
static INumber alert[] = {
    {"MaxDewP", "Dew limit from temp",  "%6.1f", -1000,0,1, -3},
    {"MaxWndS", "Wind speed limit",     "%6.1f", 0,1000,1, 25},
};
typedef enum {
    DEWPALERT, WSPDALERT
} AlertIndex;
static INumberVectorProperty alertNum = {MYDEV, "WXAlert",
    "Weather alert settings", "", IP_RW, 0, IPS_IDLE, alert, NARRAY(alert)};

/* send client definitions of all properties */
void
ISGetProperties (char const *dev)
{
	static int inited;

	if (dev && strcmp (MYDEV, dev))
	    return;

	if (!inited) {
	    /* start timer to simulate mount motion */
	    IEAddTimer (POLLMS, wxSim, NULL);
	    inited = 1;
	}

	IDDefNumber (&wxNum, NULL);
	IDDefNumber (&alertNum, NULL);
}

/* client is telling us a new INumber */
void
ISNewNumber (const char *dev, const char *name, double *doubles, char *names[],
int n)
{

	/* ignore if not ours */
	if (strcmp (dev, MYDEV))
	    return;

	if (!strcmp (name, alertNum.name) && n > 0) {
	    int i;
	    for (i = 0; i < n; i++) {
		INumber *np = IUFindNumber (&alertNum, names[i]);
		if (np) {
		    np->value = doubles[i];
		    IDSetNumber (&alertNum, "%s set to %g", np->label, np->value);
		}
	    }
	}
}

void
ISNewText (const char *dev, const char *name, char *texts[], char *names[],
int n)
{
}

void
ISNewSwitch (const char *dev, const char *name, ISState *states, char *names[],
int n)
{
}

void
ISNewBLOB (const char *dev, const char *name, int sizes[],
    int blobsizes[], char *blobs[], char *formats[], char *names[], int n)
{
}


/* update the "weather" over time */
void
wxSim (void *userpointer)
{
	wx[PRES].value += .10 * (rand() - RAND_MAX/2.)/(RAND_MAX/2.);
	wx[TEMP].value += .05 * (rand() - RAND_MAX/2.)/(RAND_MAX/2.);
	wx[DEWP].value += .05 * (rand() - RAND_MAX/2.)/(RAND_MAX/2.);
	if (wx[DEWP].value > wx[TEMP].value)
	    wx[DEWP].value = wx[TEMP].value;
	wx[WDIR].value += 2. * (rand() - RAND_MAX/2.)/(RAND_MAX/2.);
	wx[WDIR].value = fmod (wx[WDIR].value+360., 360.);
	wx[WSPD].value += 1. * (rand() - RAND_MAX/2.)/(RAND_MAX/2.);
	if (wx[WSPD].value < 0)
	    wx[WSPD].value = 0;

	sendWX();

	/* again */
	IEAddTimer (POLLMS, wxSim, NULL);
}

static void
sendWX ()
{
	char buf[128], *msg = NULL;

	if (wx[DEWP].value > wx[TEMP].value+alert[DEWPALERT].value) {
	    if (ds == IPS_OK)
		msg = "Humidity is near condensation level";
	    ds = IPS_ALERT;
	} else {
	    if (ds == IPS_ALERT)
		msg = "Condensation threat is over";
	    ds = IPS_OK;
	}

	if (wx[WSPD].value > alert[WSPDALERT].value) {
	    if (ss == IPS_OK)
		sprintf(msg=buf,"Wind speed exceeds %g",alert[WSPDALERT].value);
	    ss = IPS_ALERT;
	} else {
	    if (ss == IPS_ALERT)
		msg = "High wind warning is over";
	    ss = IPS_OK;
	}

	wxNum.s = (ss == IPS_ALERT || ds == IPS_ALERT) ? IPS_ALERT : IPS_OK;
	IDSetNumber (&wxNum, msg);
}

/* For RCS Only -- Do Not Edit */
static char *rcsid[2] = {(char *)rcsid, "@(#) $RCSfile: wx.c,v $ $Date: 2005/05/08 02:52:25 $ $Revision: 1.12 $ $Name:  $"};
