split pbmd into different files - main, header file and handlers. cleaned up code and included some voltage spike checking. also fixed the path to the save dir in the stby scripts.
authoraidan@aidan-laptop
Thu, 13 May 2010 18:16:50 +0100
changeset 1 3ca5add34a32
parent 0 55f67f57d26d
child 2 0df7d6ec3f95
split pbmd into different files - main, header file and handlers. cleaned up code and included some voltage spike checking. also fixed the path to the save dir in the stby scripts.
Makefile
handlers.h
pbmd
pbmd.c
pbmd.h
stbylong.sh
stbyshort.sh
--- a/Makefile	Fri May 07 12:04:06 2010 +0100
+++ b/Makefile	Thu May 13 18:16:50 2010 +0100
@@ -1,10 +1,10 @@
-OBJECTS=manager ifkit phidgetsbclist testlightmeter
+OBJECTS=pbmd 
 CFLAGS=-g -O0 -Wall -I../
 LIBS= -lphidget21 -lpthread -ldl
 
 all: $(OBJECTS)
 
-%: %.c
+%: %.c %.h
 	$(CC) -o $@ $^ $(CFLAGS) $(LIBS)
 
 clean:
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/handlers.h	Thu May 13 18:16:50 2010 +0100
@@ -0,0 +1,76 @@
+#ifndef HANDLERS
+#define HANDLERS
+
+#include <stdio.h>
+#include <phidget21.h>
+
+int IFK_DetachHandler(CPhidgetHandle IFK, void *userptr)
+{
+    printf("IFK Detach handler ran!\n");
+    return 0;
+}
+
+int IFK_ErrorHandler(CPhidgetHandle IFK, void *userptr, int ErrorCode, const char *unknown)
+{
+    printf("IFK Error handler ran!\n");
+    return 0;
+}
+
+int IFK_OutputChangeHandler(CPhidgetInterfaceKitHandle IFK, void *userptr, int Index, int Value)
+{
+    printf("Output %d is %d\n", Index, Value);
+    return 0;
+}
+
+int IFK_InputChangeHandler(CPhidgetInterfaceKitHandle IFK, void *userptr, int Index, int Value)
+{
+    printf("Input %d is %d\n", Index, Value);
+    return 0;
+}
+
+int IFK_SensorChangeHandler(CPhidgetInterfaceKitHandle IFK, void *userptr, int Index, int Value)
+{
+    //todo: this function doesn't appear to do anything
+
+    float fValue;
+    int oValue, rValue;
+
+    rValue = 0;
+    oValue = Value;
+
+    if (Index == 0)
+    {
+        fValue = Value;                        // Sensor 0 is Amps - adj accordingly
+        fValue = (fValue*13.2)-37.8787;        // (SensorValue / 13.2) - 37.8787
+        Value = fValue;
+    }                
+
+    return 0;
+}
+
+int IFK_AttachHandler(CPhidgetHandle IFK, void *userptr)
+{
+    CPhidgetInterfaceKit_setSensorChangeTrigger((CPhidgetInterfaceKitHandle)IFK, 0, 0);
+    printf("IFK Attach handler ran!\n");
+    return 0;
+}
+
+int LCD_AttachHandler(CPhidgetHandle IFK, void *userptr)
+{
+    printf("LCD Attach handler ran!\n");
+    return 0;
+}
+
+int LCD_DetachHandler(CPhidgetHandle IFK, void *userptr)
+{
+    printf("LCD Detach handler ran!\n");
+    return 0;
+}
+
+int LCD_ErrorHandler(CPhidgetHandle IFK, void *userptr, int ErrorCode, const char *unknown)
+{
+    printf("LCD Error handler ran!\n");
+    return 0;
+}
+
+#endif
Binary file pbmd has changed
--- a/pbmd.c	Fri May 07 12:04:06 2010 +0100
+++ b/pbmd.c	Thu May 13 18:16:50 2010 +0100
@@ -14,623 +14,100 @@
 
 #include <stdio.h>
 #include <string.h>
-#include <unistd.h>
-#include <phidget21.h>
 #include <time.h>
-#include <stdlib.h>
-
-#define INIT       0		// Initialised (first run or reset manually)
-#define STBYLONG   1		// Standby 180 - reboot, check voltage, sleep 3 hours
-#define STBYSHORT  2		// Standby 30 - boot, check voltage, sleep 30 mins
-#define OVERRIDE   3		// manually started - run 30 mins then sleep
-#define SLEEP      4 		// Sleep during the night
-#define UP         9		// Running normally - dont sleep
-#define GREEN   1150		// Voltage level for normal running
-#define AMBER 	1129		// Voltage level at which we must go asleep
-#define SLEEPTIMESTART "22:00"	// Time to start sleeping
-#define SLEEPTIMEEND   "06:00" 	// Time to end sleeping
-
-void display_generic_properties(CPhidgetHandle phid)
-{
-	int sernum, version;
-	const char *deviceptr;
-	CPhidget_getDeviceType(phid, &deviceptr);
-	CPhidget_getSerialNumber(phid, &sernum);
-	CPhidget_getDeviceVersion(phid, &version);
-
-	printf("%s\n", deviceptr);
-	printf("Version: %8d SerialNumber: %10d\n", version, sernum);
-	return;
-}
-
-int display_properties(CPhidgetTextLCDHandle phid)
-{
-	int serialNo, version, numRows, numColumns, backlight, cursor, contrast, cursor_blink;
-	const char* ptr;
-
-	CPhidget_getDeviceType((CPhidgetHandle)phid, &ptr);
-	CPhidget_getSerialNumber((CPhidgetHandle)phid, &serialNo);
-	CPhidget_getDeviceVersion((CPhidgetHandle)phid, &version);
-
-	CPhidgetTextLCD_getRowCount (phid, &numRows);
-	CPhidgetTextLCD_getColumnCount (phid, &numColumns);
-	CPhidgetTextLCD_getBacklight (phid, &backlight);
-	CPhidgetTextLCD_getContrast (phid, &contrast);
-	CPhidgetTextLCD_getCursorOn (phid, &cursor);
-	CPhidgetTextLCD_getCursorBlink (phid, &cursor_blink);
-
-	printf("%s\n", ptr);
-	printf("Serial Number: %10d\nVersion: %8d\n", serialNo, version);
-	printf("# Rows: %d\n# Columns: %d\n", numRows, numColumns);
-	printf("Current Contrast Level: %d\nBacklight Status: %d\n", contrast, backlight);
-	printf("Cursor Status: %d\nCursor Blink Status: %d\n", cursor, cursor_blink);
-
-	return 0;
-}
-
-
-int IFK_DetachHandler(CPhidgetHandle IFK, void *userptr)
-{
-	printf("IFK Detach handler ran!\n");
-	return 0;
-}
-
-int IFK_ErrorHandler(CPhidgetHandle IFK, void *userptr, int ErrorCode, const char *unknown)
-{
-	printf("IFK Error handler ran!\n");
-	return 0;
-}
-
-int IFK_OutputChangeHandler(CPhidgetInterfaceKitHandle IFK, void *userptr, int Index, int Value)
-{
-	printf("Output %d is %d\n", Index, Value);
-	return 0;
-}
-
-int IFK_InputChangeHandler(CPhidgetInterfaceKitHandle IFK, void *userptr, int Index, int Value)
-{
-	printf("Input %d is %d\n", Index, Value);
-	return 0;
-}
-
-int IFK_SensorChangeHandler(CPhidgetInterfaceKitHandle IFK, void *userptr, int Index, int Value)
-{
-	float fValue;
-	int oValue, rValue;
-
-	rValue = 0;
-	oValue = Value;
-
-
-	if (Index == 0) {
-		fValue = Value;				// Sensor 0 is Amps - adj accordingly
-		fValue = (fValue*13.2)-37.8787;		// (SensorValue / 13.2) - 37.8787
-		Value = fValue;
-		}				
-
-	return 0;
-}
-
-
-int IFK_AttachHandler(CPhidgetHandle IFK, void *userptr)
-{
-	CPhidgetInterfaceKit_setSensorChangeTrigger((CPhidgetInterfaceKitHandle)IFK, 0, 0);
-	printf("IFK Attach handler ran!\n");
-	return 0;
-}
-
-int LCD_AttachHandler(CPhidgetHandle IFK, void *userptr)
-{
-	printf("LCD Attach handler ran!\n");
-	return 0;
-}
-
-int LCD_DetachHandler(CPhidgetHandle IFK, void *userptr)
-{
-	printf("LCD Detach handler ran!\n");
-	return 0;
-}
-
-int LCD_ErrorHandler(CPhidgetHandle IFK, void *userptr, int ErrorCode, const char *unknown)
-{
-	printf("LCD Error handler ran!\n");
-	return 0;
-}
-
-
-int getVoltage(CPhidgetInterfaceKitHandle IFK, int voltIndex, int *Voltage)
-{
-	float fValue = 0, avgValue = 0;
-	int Value= 0, i = 0;
-
-	CPhidgetInterfaceKit_setRatiometric(IFK, PFALSE);		// set to non-ratio
-	sleep(2);							// wait at least 800ms to settle
-	CPhidgetInterfaceKit_getSensorRawValue(IFK, voltIndex, &Value);	// Voltmeter
-
-	// Calibration							// this is zero point calibration.
-	Value = Value + 5;
-	// End calibration
-
-	// get an average over 5 readings to allow for sensor noise. 1 per second for 5 seconds
-
-	for (i = 0; i < 5 ; i++)
-	{
-		fValue = Value;
-		fValue = (((fValue/4.095)*0.06)-30)*100;    // multiply raw value and up by 100 to keep
-		avgValue = avgValue + fValue;
-		sleep (1);
-	}
-		avgValue = avgValue / 5;
-		*Voltage = avgValue;
-
-//	printf("Volts value %d\n", Value);
-
-	return 0;
-}
-
-int getAmps(CPhidgetInterfaceKitHandle IFK, int ampIndex, int *Amps)
-{
-	float fValue;
-	int Value,nValue;
-
-		CPhidgetInterfaceKit_setRatiometric (IFK, PTRUE);		// set to ratiometric
-		sleep(2);							// wait at least 800ms
-		CPhidgetInterfaceKit_getSensorRawValue(IFK, ampIndex, &Value);	// Ampmeter
-		CPhidgetInterfaceKit_getSensorValue(IFK, ampIndex, &nValue);
-
-		// Calibration
-		Value = Value + 2;
-		// End calibration
-
-		fValue = Value;
-		fValue = (((fValue/4.095)/13.2)-37.8787)*1000;	// multiply raw value to get amps
-		*Amps = fValue;
-
-//	printf("Amps value Raw %d Normal %d\n", Value, nValue);
-	return 0;
-}
-
-int getLux(CPhidgetInterfaceKitHandle IFK, int luxIndex, int *Lux)
-{
-	int Value;
-
-		CPhidgetInterfaceKit_setRatiometric(IFK, PFALSE);		// set to non-ratio
-		sleep(2);							// wait at least 800ms
-		CPhidgetInterfaceKit_getSensorValue(IFK, luxIndex, &Value);	// Voltmeter
-
-		// Calibration
-		// None required
-		// End calibration
-
-		*Lux = Value;
-
-//	printf("Volts value %d\n", Value);
-	return 0;
-}
-
-
-int updateSnapshotfile(char *SNAPSHOTFILE, int newState, int Voltage, int Amps, int Lux)
-{
-	// Snapshot file is a single line file, overwritten each time with the current and latest values
-  	time_t rawtime;
-  	struct tm * timeinfo;
-  	char timeStr [80];
-
-  	time ( &rawtime );
-  	timeinfo = localtime ( &rawtime );
-
-  	strftime (timeStr,80,"%Y-%m-%d,%H:%M:%S",timeinfo);
-
-      	FILE *filesnap = fopen( SNAPSHOTFILE, "w" );			// Open file (delete previous)
-
-       	if (filesnap == 0)		// Aaargh! Problem ...
-       	{
-        	printf( "Could not open the snapshot file\n" );
-      	}
-     	  else 
-      	  {
-		fprintf(filesnap, "%d,%s,%d,%d,%d\n", newState, timeStr, Voltage, Amps, Lux);
-		fflush(filesnap);
-	  }
-	fclose( filesnap );
-
-	return 0;
-}
-
-
-
-int updateLogfile(FILE *filelog, int Voltage, int Amps, int Lux)
-{
-  	time_t rawtime;
-  	struct tm * timeinfo;
-  	char timeStr [80];
-
-  	time ( &rawtime );
-  	timeinfo = localtime ( &rawtime );
-
-  	strftime (timeStr,80,"%Y-%m-%d,%H:%M:%S",timeinfo);
-
-	fprintf(filelog, "%s,%d,%d,%d\n", timeStr, Voltage, Amps, Lux);
-	fflush(filelog);
-
-	return 0;
-}
-
-
-// getTimeString returns the time in a string in the form "HH:MM". It takes the current
-// time and adds the wakeTime to it. This can also be used to simply return the current time if the
-// wakeTime is 0.
-
-int getTimeString (int wakeTime, char *wakeTimeStr)
-{
-  	time_t rawtime;
-  	struct tm * timeinfo;
-
-  	time ( &rawtime );
-	rawtime = rawtime + (wakeTime * 60);
-  	timeinfo = localtime ( &rawtime );
-
- // 	strftime (wakeTimeStr,80,"%Y-%m-%d,%H:%M:%S",timeinfo);
- 	strftime (wakeTimeStr,20,"%H:%M",timeinfo);
-
-	return 0;
-}
-
-int getState(char *SNAPSHOTFILE, int previousState, char *bootflag)
-{
-	// Snapshot file is a single line file, overwritten each time with the current and latest values
-
-      	FILE *filesnap = fopen( SNAPSHOTFILE, "r" );			// Open file (delete previous)
-
-       	if (filesnap == 0)		// Aaargh! Problem ...
-       	{
-        	printf( "getState: Could not open the snapshot file to retrieve state\n" );
-      	}
-     	  else 
-      	  {
-		//fprintf(filesnap, "%s,%d,%d,%d\n", timeStr, Voltage, Amps, Lux);
-		//fflush(filesnap);
-	  }
-	fclose( filesnap );
-
-	return 0;
-}
-
-int getnewState(int Voltage, char *bootflag, int *newState)
-{
-	char *timeStr = malloc(20);
-
-	int localState = 0;
-
-	printf ("In getnewState: Bootflag %s Voltage %d\n", bootflag, Voltage);
-
-	*newState = localState;				// Just to be sure its 0}
-
-	getTimeString (0, timeStr);			// Use this to return current time as a string
-
-	if (strncmp(bootflag, "S",1) != 0) {		// Anything except an S will mean manual start
-	    localState = OVERRIDE;
-	    }
-	else if (strcmp(timeStr, SLEEPTIMESTART) > 0 || strcmp(timeStr, SLEEPTIMEEND) < 0) {
-	    localState = SLEEP;
-            }
-	else if (Voltage >= GREEN) {
-	    localState = UP;
-            }
-	else if (Voltage >= AMBER) {
-	    localState = STBYSHORT;
-	    }
-        else {
-	    localState = STBYLONG;
-	    } 
-
-	*newState = localState;				// and set it across the wormhole
-
-	return 0;
-}
-
-int test_interfacekit(FILE *filelog, char *SNAPSHOTFILE, char * bootflag, time_t boottime, int Sleep, int testVoltage)
-{
-	int LUXINDEX=2;
-	int VOLTINDEX=1;
-	int AMPINDEX=0;
-
-	int numInputs, numOutputs, numSensors;
-	int err;
-	int lightTrigger;
-	int Voltage = 0, Amps = 0, Lux = 0;
-	int tts;
-	int newState = 0;
-	int ret;
-
-  	char buffer1 [80];
-  	char buffer2 [80];
-	char *wakeTimeStr = malloc(20);
-
-	char *stateDesc[10];
-
-	time_t timenow;
-
-	stateDesc[0] = "Initialise";
-	stateDesc[1] = "STBYLONG";
-	stateDesc[2] = "STBYSHORT";
-	stateDesc[3] = "OVERRIDE";
-	stateDesc[4] = "SLEEP";
-	stateDesc[9] = "UP";
-
-	CPhidgetInterfaceKitHandle IFK = 0;
-	CPhidgetInterfaceKit_create(&IFK);
-
-	CPhidgetTextLCDHandle LCD = 0;
-	CPhidgetTextLCD_create (&LCD);
-
-	//CPhidget_enableLogging(PHIDGET_LOG_VERBOSE, NULL);
-
-	// Set up handlers for the Interface Kit
-
-	CPhidget_set_OnAttach_Handler((CPhidgetHandle)IFK, IFK_AttachHandler, NULL);
-	CPhidget_set_OnDetach_Handler((CPhidgetHandle)IFK, IFK_DetachHandler, NULL);
-	CPhidget_set_OnError_Handler((CPhidgetHandle)IFK, IFK_ErrorHandler, NULL);
-
-	// Set up handlers for the TextLCD
-
-	CPhidget_set_OnAttach_Handler((CPhidgetHandle)LCD, LCD_AttachHandler, NULL);
-	CPhidget_set_OnDetach_Handler((CPhidgetHandle)LCD, LCD_DetachHandler, NULL);
-	CPhidget_set_OnError_Handler((CPhidgetHandle)LCD, LCD_ErrorHandler, NULL);
-			
-	CPhidget_open((CPhidgetHandle)IFK, -1);
-	CPhidget_open((CPhidgetHandle)LCD, -1);
-
-	//wait 5 seconds for attachment of the Interface Kit
-	printf("Waiting for IFK to be attached...\n");
-	if((err = CPhidget_waitForAttachment((CPhidgetHandle)IFK, 5000)) != EPHIDGET_OK )
-	{
-		const char *errStr;
-		CPhidget_getErrorDescription(err, &errStr);
-		printf("Error waiting for IFK attachment: (%d): %s\n",err,errStr);
-		goto exit;
-	}
-	
-	display_generic_properties((CPhidgetHandle)IFK);
-	CPhidgetInterfaceKit_getOutputCount((CPhidgetInterfaceKitHandle)IFK, &numOutputs);
-	CPhidgetInterfaceKit_getInputCount((CPhidgetInterfaceKitHandle)IFK, &numInputs);
-	CPhidgetInterfaceKit_getSensorCount((CPhidgetInterfaceKitHandle)IFK, &numSensors);
-	
-	CPhidgetInterfaceKit_setOutputState((CPhidgetInterfaceKitHandle)IFK, 0, 1);
-
-	printf("Sensors:%d Inputs:%d Outputs:%d\n", numSensors, numInputs, numOutputs);
-
-	//get the program to wait for an TextLCD device to be attached
-	printf("Waiting for LCD to be attached...\n");
-	if((err = CPhidget_waitForAttachment((CPhidgetHandle)LCD, 10000)))
-	{
-		const char *errStr;
-		CPhidget_getErrorDescription(err, &errStr);
-		printf("Problem waiting for LCD attachment: (%d): %s\n",err,errStr);
-		return 0;
-	}
-
-	//Display the properties of the attached textlcd device
-	display_properties(LCD);
-
-
-	CPhidgetInterfaceKit_getSensorChangeTrigger (IFK, 0, &lightTrigger);
-
-
-	while(1)
-	{
-		getVoltage(IFK, VOLTINDEX, &Voltage);
-		getAmps(IFK, AMPINDEX, &Amps);
-		getLux(IFK, LUXINDEX, &Lux);
-
-
-		if (testVoltage != 0) {
-			Voltage = testVoltage;
-		}
-
-		getnewState (Voltage, bootflag, &newState);
-
-		updateLogfile (filelog, Voltage, Amps, Lux);
-
-		updateSnapshotfile (SNAPSHOTFILE, newState, Voltage, Amps, Lux);
-
-	// Now Update the LCD
-
-		getTimeString (0, wakeTimeStr);
-		sprintf (buffer1, "V:%4d A:%-5d %s", Voltage, Amps,wakeTimeStr);
-		sprintf (buffer2, "%-s", stateDesc[newState]);
-
-		CPhidgetTextLCD_setDisplayString (LCD, 0, buffer1);
-		CPhidgetTextLCD_setDisplayString (LCD, 1, buffer2);
-	
-
-
-	// Do what the state demands
-	printf ("Begin main while loop: State is %s\n", stateDesc[newState]);
-
-	switch (newState)
-	{
-	case INIT:
-	    // Shouldnt be here!
-	    break;
-
-	case STBYLONG:
-	    // sleep for 3 hours, then wake, reboot
-		getTimeString (180, wakeTimeStr);
-		sprintf (buffer2, "%-s Back@%-s", stateDesc[newState], wakeTimeStr);
-
-		CPhidgetTextLCD_setDisplayString (LCD, 1, buffer2);
-		
-		ret = system ("/etc/stbylong.sh");
-		if (!ret) {
-		    printf ("STBYLONG - executing ...\n");
-		}
-		else {
-		    printf ("STBYLONG - problem kicking off STBYLONG ... not running. Error %d\n",ret);
-		}
-	    break;
-
-	case STBYSHORT:
-	    // sleep for 30 mins, then wake, reboot
-		getTimeString (30, wakeTimeStr);
-		sprintf (buffer2, "%-s Wake@%-s", stateDesc[newState], wakeTimeStr);
-
-		CPhidgetTextLCD_setDisplayString (LCD, 1, buffer2);
-		
-		ret = system ("/etc/stbyshort.sh");
-		if (!ret) {
-		    printf ("STBYSHORT - executing ...\n");
-		}
-		else {
-		    printf ("STBYSHORT - problem kicking off STBYSHORT ... not running. Error %d\n",ret);
-		}
-	    break;
-
-	case OVERRIDE:
-	    // stay up for 30 mins, then sleep, wake, reboot
-	        time (&timenow);
-		tts = 1800 - (timenow - boottime);
-		printf ("%d to sleep\n", tts);
-
-		sprintf (buffer2, "%-s Time:%d", stateDesc[newState], tts/60);
-
-		CPhidgetTextLCD_setDisplayString (LCD, 1, buffer2);
-
-		if (timenow > boottime + 1800) {
-
-		    printf ("OVERRIDE - 30 mins expired ... switching to normal mode\n");
-		    bootflag = "S";
-		    printf ("Bootflag in case OVERRIDE %s \n", bootflag);
-		}
-	    break;
-
-	case SLEEP:
-	    // We're running during night time - go to sleep
-		wakeTimeStr = SLEEPTIMEEND;
-		sprintf (buffer2, "%-s Wake@%-s", stateDesc[newState], wakeTimeStr);
-
-		CPhidgetTextLCD_setDisplayString (LCD, 1, buffer2);
-		
-		ret = system ("/etc/sleeprtc.sh");
-		if (!ret) {
-		    printf ("SLEEPRTC - executing ...\n");
-		}
-		else {
-		    printf ("SLEEPRTC - problem kicking off SLEEPRTC ... not running. Error %d\n",ret);
-		}
-	    break;
-	case UP:
-	    // normal running here
-	    // Nothing to do but continue loop
-	    break;
-	}
-
-	fflush (stdout);
-	sleep (Sleep);
-
-	}
-
-exit:
-	CPhidget_close((CPhidgetHandle)IFK);
-	CPhidget_delete((CPhidgetHandle)IFK);
-	CPhidget_close((CPhidgetHandle)LCD);
-	CPhidget_delete((CPhidgetHandle)LCD);
-
-	return 0;
-}
-
-
+#include "pbmd.h"
 
 int main(int argc, char* argv[])
 {
-   int Sleep, testVoltage;
-   char *SNAPSHOTFILE;
-   char *bootflag = malloc(2);
-   time_t boottime;
+    int Sleep, testVoltage;
+    char *SNAPSHOTFILE;
+    char *bootflag = malloc(2);
+    time_t boottime;
+
+    if ( argc != 6 ) // 5 args inc program name
+    {                            
+        printf( "usage: %s logfile snapshotfile rebootfile sleeptime testvoltage\n", argv[0] );
+        exit(1);
+    }
+ 
+    // Close out stdout and point to a file cos if we are running as a demon we need to log this somewhere.
+    fclose(stdout);
+    fclose(stderr);
+    stdout = fopen("/var/log/pbm.log", "a");
+    stderr = fopen("/var/log/pbm.err", "a");
+
+    Sleep = atoi(argv[4]);          // Arg 4 is sleep interval
+    testVoltage = atoi(argv[5]);    // Arg 5 is used for testing
+                                    // - 0 is use voltmeter reading
+                                    // - any other value overrides
+
+    FILE *filelog = fopen( argv[1], "a" );      // Open log file
+    FILE *filesnap = fopen( argv[2], "w" );     // Open snapshot file
+
+    if ( (filelog == 0) || (filesnap == 0))     // Aaargh! Problem ...
+    {            
+        printf( "Could not open log file or snapshot file\n" );
+        exit(1);
+    }
+
+    fclose( filesnap );            // cos we need to overwrite it every time we write to it
+
+    // The system reboots after a sleep period to ensure everyting is restarted properly
+    // As part of this "planned" reboot the boot flag file is written to.
+    // If this file does not have the correct value, then a user has powered off/on the box
+    // in order to force a wakeup, so we dont want to go asleep straight away
+    // If the value is S then we have scheduled a wakeup. Anything else, or no file means manual
+    // override.
+
+    FILE *fileboot = fopen( argv[3], "r");        // Open boot flag file
+    if ( (fileboot == 0) ) 
+    {
+        printf( "Could not open boot flag file - assuming manual override\n" );
+        bootflag = "N";
+    }
+    else 
+    {
+        // read from boot state file
+        printf( "Opened boot flag file\n");
+        // bootflag should be "S"
+        if (fscanf (fileboot, "%s", bootflag)) 
+        {
+            time ( &boottime );        // log time we booted            
+            fclose( fileboot );
+        }
+        else 
+        {
+            printf( "Error reading in from bootflag file - assuming manual restart\n" );
+            bootflag = "X";
+        }
+    }
 
 
-   if ( argc != 6 ) {							// 5 args inc program name
-            printf( "usage: %s logfile snapshotfile rebootfile sleeptime testvoltage\n", argv[0] );
-	    exit(1);
-    	}
- 
-	// Close out stdout and point to a file cos if we are running as a demon we need to log this somewhere.
-
-	fclose(stdout);
-	fclose(stderr);
-	stdout = fopen("/var/log/pbm.log", "a");
-	stderr = fopen("/var/log/pbm.err", "a");
-
-	Sleep = atoi(argv[4]);						// Arg 4 is sleep interval
-	testVoltage = atoi(argv[5]);					// Arg 5 is used for testing
-									// - 0 is use voltmeter reading
-									// - any other value overrides
+    // clear bootflag file - an S in this file means we are controlling the reboot (eg the user
+    // did not manually turn off and on the box
 
-	FILE *filelog = fopen( argv[1], "a" );				// Open log file
-        FILE *filesnap = fopen( argv[2], "w" );				// Open snapshot file
-
-        if ( (filelog == 0) || (filesnap == 0))	{			// Aaargh! Problem ...
-            printf( "Could not open log file or snapshot file\n" );
-	    exit(1);
-        }
-
-	fclose( filesnap );			// cos we need to overwrite it every time we write to it
-
-	// The system reboots after a sleep period to ensure everyting is restarted properly
-	// As part of this "planned" reboot the boot flag file is written to.
-	// If this file does not have the correct value, then a user has powered off/on the box
-	// in order to force a wakeup, so we dont want to go asleep straight away
-	// If the value is S then we have scheduled a wakeup. Anything else, or no file means manual
-	// override.
+    fileboot = fopen( argv[3], "w");        // Open boot flag file for writing
+    if ( (fileboot == 0) ) 
+        printf( "Could not open boot flag file for writing\n" );        
+    else    // read from boot state file 
+    {  
+        printf( "Clearing boot flag\n");
+        fprintf(fileboot, "%s", "X");
+        fclose( fileboot );
+    }    
 
-	FILE *fileboot = fopen( argv[3], "r");		// Open boot flag file
-	if ( (fileboot == 0) ) {
-		printf( "Could not open boot flag file - assuming manual override\n" );
-		bootflag = "N";
-	}
-	else {
-	// read from boot state file
-	    printf( "Opened boot flag file\n");
-		    // bootflag should be "S"
-	    if (fscanf (fileboot, "%s", bootflag)) {
-		time ( &boottime );		// log time we booted			
-		fclose( fileboot );
-	    }
-	    else {
-		printf( "Error reading in from bootflag file - assuming manual restart\n" );
-		bootflag = "X";
-	    }
-	}
-
-
-// clear bootflag file - an S in this file means we are controlling the reboot (eg the user
-// did not manually turn off and on the box
+    printf ("Output to file %s\n", argv[1]);
+    printf ("Output to snapshot %s\n", argv[2]);
+    printf ("Boot flag file is %s\n", argv[3]);
+    printf ("Sleep time is %d\n", Sleep);
+    printf ("Bootflag is %s\n", bootflag);
 
-	fileboot = fopen( argv[3], "w");		// Open boot flag file for writing
-	if ( (fileboot == 0) ) {
-		printf( "Could not open boot flag file for writing\n" );
-	}
-	else {  // read from boot state file
-		printf( "Clearing boot flag\n");
-		fprintf(fileboot, "%s", "X");
-		fclose( fileboot );
-		}
-
-
+    fprintf (filelog, "\nYYYY-M-MDD,HH:MM:SS,mVolts,mAmps,Lux\n");
 
-	printf ("Output to file %s\n", argv[1]);
-	printf ("Output to snapshot %s\n", argv[2]);
-	printf ("Boot flag file is %s\n", argv[3]);
-	printf ("Sleep time is %d\n", Sleep);
-	printf ("Bootflag is %s\n", bootflag);
+    SNAPSHOTFILE = argv[2];
 
-	fprintf (filelog, "\nYYYY-M-MDD,HH:MM:SS,mVolts,mAmps,Lux\n");
-
-	SNAPSHOTFILE = argv[2];
-
-	test_interfacekit(filelog, SNAPSHOTFILE, bootflag, boottime, Sleep, testVoltage);// and off we go
+    test_interfacekit(filelog, SNAPSHOTFILE, bootflag, boottime, Sleep, testVoltage);// and off we go
         
-
     fclose( filelog );
     return 0;
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/pbmd.h	Thu May 13 18:16:50 2010 +0100
@@ -0,0 +1,429 @@
+#ifndef PBMD
+#define PBMD
+
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <phidget21.h>
+#include <time.h>
+#include <stdlib.h>
+#include "handlers.h"
+
+#define INIT       0        // Initialised (first run or reset manually)
+#define STBYLONG   1        // Standby 180 - reboot, check voltage, sleep 3 hours
+#define STBYSHORT  2        // Standby 30 - boot, check voltage, sleep 30 mins
+#define OVERRIDE   3        // manually started - run 30 mins then sleep
+#define SLEEP      4        // Sleep during the night
+#define UP         9        // Running normally - dont sleep
+#define GREEN   1150        // Voltage level for normal running
+#define AMBER   1129        // Voltage level at which we must go asleep
+#define SLEEPTIMESTART "22:00"    // Time to start sleeping
+#define SLEEPTIMEEND   "06:00"    // Time to end sleeping
+
+void display_generic_properties(CPhidgetHandle phid)
+{
+    int sernum, version;
+    const char *deviceptr;
+    
+    CPhidget_getDeviceType(phid, &deviceptr);
+    CPhidget_getSerialNumber(phid, &sernum);
+    CPhidget_getDeviceVersion(phid, &version);
+
+    printf("%s\n", deviceptr);
+    printf("Version: %8d SerialNumber: %10d\n", version, sernum);
+}
+
+void display_properties(CPhidgetTextLCDHandle phid)
+{
+    int numRows, numColumns, backlight, cursor, contrast, cursor_blink;
+
+    CPhidgetTextLCD_getRowCount (phid, &numRows);
+    CPhidgetTextLCD_getColumnCount (phid, &numColumns);
+    CPhidgetTextLCD_getBacklight (phid, &backlight);
+    CPhidgetTextLCD_getContrast (phid, &contrast);
+    CPhidgetTextLCD_getCursorOn (phid, &cursor);
+    CPhidgetTextLCD_getCursorBlink (phid, &cursor_blink);
+
+    display_generic_properties((CPhidgetHandle) phid);
+    
+    printf("# Rows: %d\n# Columns: %d\n", numRows, numColumns);
+    printf("Current Contrast Level: %d\nBacklight Status: %d\n", contrast, backlight);
+    printf("Cursor Status: %d\nCursor Blink Status: %d\n", cursor, cursor_blink);
+}
+
+void getVoltage(CPhidgetInterfaceKitHandle IFK, int voltIndex, int *Voltage)
+{
+    float fValue = 0, avgValue = 0;
+    int Value = 0, i = 0;
+
+    CPhidgetInterfaceKit_setRatiometric(IFK, PFALSE);                // set to non-ratio
+    sleep(2);                                                        // wait at least 800ms to settle
+    CPhidgetInterfaceKit_getSensorRawValue(IFK, voltIndex, &Value);  // Voltmeter
+
+    // Calibration - this is zero point calibration.
+    Value += 5;
+    // End calibration
+
+    // get an average over 5 readings to allow for sensor noise. 1 per second for 5 seconds
+    for (i = 0; i < 5 ; i++)
+    {
+        fValue = Value;
+        fValue = (((fValue/4.095)*0.06)-30)*100;    // multiply raw value and up by 100 to keep
+        avgValue += fValue;
+        sleep (1);
+    }
+            
+    *Voltage = avgValue / 5;
+
+//    printf("Volts value %d\n", Value);
+}
+
+void getAmps(CPhidgetInterfaceKitHandle IFK, int ampIndex, int *Amps)
+{
+    float fValue;
+    int Value;
+//    int nValue;
+
+    CPhidgetInterfaceKit_setRatiometric (IFK, PTRUE);                // set to ratiometric
+    sleep(2);                                                        // wait at least 800ms
+    CPhidgetInterfaceKit_getSensorRawValue(IFK, ampIndex, &Value);   // Ampmeter
+//    CPhidgetInterfaceKit_getSensorValue(IFK, ampIndex, &nValue);
+
+    // Calibration
+    Value += 2;
+    // End calibration    currVoltTime
+
+    fValue = Value;
+    fValue = (((fValue/4.095)/13.2)-37.8787)*1000;    // multiply raw value to get amps
+    *Amps = fValue;
+
+//    printf("Amps value Raw %d Normal %d\n", Value, nValue);
+}
+
+void getLux(CPhidgetInterfaceKitHandle IFK, int luxIndex, int *Lux)
+{
+    int Value;
+
+    CPhidgetInterfaceKit_setRatiometric(IFK, PFALSE);                // set to non-ratio
+    sleep(2);                                                        // wait at least 800ms
+    CPhidgetInterfaceKit_getSensorValue(IFK, luxIndex, &Value);      // Voltmeter
+
+    // Calibration
+    // None required
+    // End calibration
+
+    *Lux = Value;
+
+//    printf("Volts value %d\n", Value);
+}
+
+
+void updateSnapshotfile(char *SNAPSHOTFILE, int newState, int Voltage, int Amps, int Lux)
+{
+    // Snapshot file is a single line file, overwritten each time with the current and latest values
+    time_t rawtime;
+    struct tm * timeinfo;
+    char timeStr [80];
+
+    time ( &rawtime );
+    timeinfo = localtime ( &rawtime );
+
+    strftime (timeStr,80,"%Y-%m-%d,%H:%M:%S",timeinfo);
+
+    FILE *filesnap = fopen( SNAPSHOTFILE, "w" );            // Open file (delete previous)
+
+    if (filesnap == 0)        // Aaargh! Problem ...
+        printf( "Could not open the snapshot file\n" );
+    else 
+    {
+        fprintf(filesnap, "%d,%s,%d,%d,%d\n", newState, timeStr, Voltage, Amps, Lux);
+        fflush(filesnap);
+    }
+    fclose( filesnap );
+}
+
+void updateLogfile(FILE *filelog, int Voltage, int Amps, int Lux)
+{
+    time_t rawtime;
+    struct tm * timeinfo;
+    char timeStr [80];
+
+    time ( &rawtime );
+    timeinfo = localtime ( &rawtime );
+
+    strftime (timeStr,80,"%Y-%m-%d,%H:%M:%S",timeinfo);
+
+    fprintf(filelog, "%s,%d,%d,%d\n", timeStr, Voltage, Amps, Lux);
+    fflush(filelog);
+}
+
+
+// getTimeString returns the time in a string in the form "HH:MM". It takes the current
+// time and adds the wakeTime to it. This can also be used to simply return the current time if the
+// wakeTime is 0.
+void getTimeString (int wakeTime, char *wakeTimeStr)
+{
+    time_t rawtime;
+    struct tm * timeinfo;
+
+    time ( &rawtime );
+    rawtime = rawtime + (wakeTime * 60);
+    timeinfo = localtime ( &rawtime );
+
+    //strftime (wakeTimeStr,80,"%Y-%m-%d,%H:%M:%S",timeinfo);
+    strftime (wakeTimeStr,20,"%H:%M",timeinfo);
+}
+
+void getnewState(int Voltage, char *bootflag, int *newState)
+{
+    char *timeStr = malloc(20);
+    int localState = 0;
+
+    printf ("In getnewState: Bootflag %s Voltage %d\n", bootflag, Voltage);
+
+    *newState = localState;                 // Just to be sure its 0
+    getTimeString (0, timeStr);             // Use this to return current time as a string
+
+    if (strncmp(bootflag, "S",1) != 0)      // Anything except an S will mean manual start
+        localState = OVERRIDE;
+    
+    else if (strcmp(timeStr, SLEEPTIMESTART) > 0 || strcmp(timeStr, SLEEPTIMEEND) < 0) 
+        localState = SLEEP;
+    
+    else if (Voltage >= GREEN) 
+        localState = UP;
+    
+    else if (AMBER <= Voltage && Voltage < GREEN) 
+        localState = STBYSHORT;
+
+    else //Voltage < AMBER
+        localState = STBYLONG;         
+
+    *newState = localState;                // and set it across the wormhole
+    free(timeStr);
+}
+
+void closeCPhidget(CPhidgetHandle handle)
+{
+    CPhidget_close(handle);
+    CPhidget_delete(handle);
+}
+
+void test_interfacekit(FILE *filelog, char *SNAPSHOTFILE, char * bootflag, time_t boottime, int Sleep, int testVoltage)
+{
+    int LUXINDEX=2;
+    int VOLTINDEX=1;
+    int AMPINDEX=0;
+
+    int numInputs, numOutputs, numSensors;
+    int err;
+    int lightTrigger;
+    int prevVoltage = 0, Voltage = 0, Amps = 0, Lux = 0;
+    int tts;
+    int newState = 0;
+    int ret;
+    int deltaVoltage = 0;
+    const int maxDeltaVoltage = 500;//todo: check this value 
+    const int timeStep = 60;
+
+    char buffer1 [80];
+    char buffer2 [80];
+    char *wakeTimeStr = malloc(20);
+
+    char *stateDesc[10];
+
+    time_t timenow, prevVoltTime, currVoltTime;
+
+    stateDesc[0] = "Initialise";
+    stateDesc[1] = "STBYLONG";
+    stateDesc[2] = "STBYSHORT";
+    stateDesc[3] = "OVERRIDE";
+    stateDesc[4] = "SLEEP";
+    stateDesc[9] = "UP";
+
+    CPhidgetInterfaceKitHandle IFK = 0;
+    CPhidgetInterfaceKit_create(&IFK);
+
+    CPhidgetTextLCDHandle LCD = 0;
+    CPhidgetTextLCD_create (&LCD);
+
+    //CPhidget_enableLogging(PHIDGET_LOG_VERBOSE, NULL);
+
+    // Set up handlers for the Interface Kit
+
+    CPhidget_set_OnAttach_Handler((CPhidgetHandle)IFK, IFK_AttachHandler, NULL);
+    CPhidget_set_OnDetach_Handler((CPhidgetHandle)IFK, IFK_DetachHandler, NULL);
+    CPhidget_set_OnError_Handler((CPhidgetHandle)IFK, IFK_ErrorHandler, NULL);
+
+    // Set up handlers for the TextLCD
+
+    CPhidget_set_OnAttach_Handler((CPhidgetHandle)LCD, LCD_AttachHandler, NULL);
+    CPhidget_set_OnDetach_Handler((CPhidgetHandle)LCD, LCD_DetachHandler, NULL);
+    CPhidget_set_OnError_Handler((CPhidgetHandle)LCD, LCD_ErrorHandler, NULL);
+            
+    CPhidget_open((CPhidgetHandle)IFK, -1);
+    CPhidget_open((CPhidgetHandle)LCD, -1);
+
+    //wait 5 seconds for attachment of the Interface Kit
+    printf("Waiting for IFK to be attached...\n");
+    if((err = CPhidget_waitForAttachment((CPhidgetHandle)IFK, 5000)) != EPHIDGET_OK )
+    {
+        const char *errStr;
+        CPhidget_getErrorDescription(err, &errStr);
+        printf("Error waiting for IFK attachment: (%d): %s\n",err,errStr);
+
+        closeCPhidget((CPhidgetHandle)IFK);
+        closeCPhidget((CPhidgetHandle)LCD);
+        return;
+    }
+    
+    display_generic_properties((CPhidgetHandle)IFK);
+    CPhidgetInterfaceKit_getOutputCount((CPhidgetInterfaceKitHandle)IFK, &numOutputs);
+    CPhidgetInterfaceKit_getInputCount((CPhidgetInterfaceKitHandle)IFK, &numInputs);
+    CPhidgetInterfaceKit_getSensorCount((CPhidgetInterfaceKitHandle)IFK, &numSensors);
+    
+    CPhidgetInterfaceKit_setOutputState((CPhidgetInterfaceKitHandle)IFK, 0, 1);
+
+    printf("Sensors:%d Inputs:%d Outputs:%d\n", numSensors, numInputs, numOutputs);
+
+    //get the program to wait 10 seconds for an TextLCD device to be attached
+    printf("Waiting for LCD to be attached...\n");
+    if((err = CPhidget_waitForAttachment((CPhidgetHandle)LCD, 10000)))
+    {
+        const char *errStr;
+        CPhidget_getErrorDescription(err, &errStr);
+        printf("Problem waiting for LCD attachment: (%d): %s\n",err,errStr);
+
+        closeCPhidget((CPhidgetHandle)IFK);
+        closeCPhidget((CPhidgetHandle)LCD);
+        return;
+    }
+
+    //Display the properties of the attached textlcd device
+    display_properties(LCD);
+
+    CPhidgetInterfaceKit_getSensorChangeTrigger (IFK, 0, &lightTrigger);
+    
+    prevVoltTime = 0;                               //initialise previous voltage time 
+    getVoltage(IFK, VOLTINDEX, &Voltage);           //ininitalise voltage
+    
+    while(1)
+    {
+        prevVoltage = Voltage;                      //store last voltage
+        getVoltage(IFK, VOLTINDEX, &Voltage);       //get new voltage
+        time (&currVoltTime);
+
+        deltaVoltage = (Voltage - prevVoltage) < 0 ? -1 * (Voltage - prevVoltage) : (Voltage - prevVoltage);              
+
+        //if the change in voltage is greater than the max allowable change in the given time step, a spike has occured
+        if(deltaVoltage > maxDeltaVoltage && (currVoltTime - prevVoltTime) < timeStep)
+        {
+            printf("Voltage spike from: (%d) to: (%d) in %ld seconds\n", prevVoltage, Voltage, (currVoltTime - prevVoltTime));
+            //todo: consider how to handle this spike
+        }               
+        prevVoltTime = currVoltTime;                //store last time 
+        
+        getAmps(IFK, AMPINDEX, &Amps);
+        getLux(IFK, LUXINDEX, &Lux);
+
+        if (testVoltage != 0) 
+            Voltage = testVoltage;        
+
+        getnewState (Voltage, bootflag, &newState);
+
+        updateLogfile (filelog, Voltage, Amps, Lux);
+
+        updateSnapshotfile (SNAPSHOTFILE, newState, Voltage, Amps, Lux);
+
+        // Now Update the LCD
+
+        getTimeString (0, wakeTimeStr);
+        sprintf (buffer1, "V:%4d A:%-5d %s", Voltage, Amps,wakeTimeStr);
+        sprintf (buffer2, "%-s", stateDesc[newState]);
+
+        CPhidgetTextLCD_setDisplayString (LCD, 0, buffer1);
+        CPhidgetTextLCD_setDisplayString (LCD, 1, buffer2);
+    
+        // Do what the state demands
+        printf ("Begin main while loop: State is %s\n", stateDesc[newState]);
+        
+        if(newState == STBYLONG)
+        {
+            // sleep for 3 hours, then wake, reboot
+            getTimeString (180, wakeTimeStr);
+            sprintf (buffer2, "%-s Back@%-s", stateDesc[newState], wakeTimeStr);
+            
+            CPhidgetTextLCD_setDisplayString (LCD, 1, buffer2);
+        
+            ret = system ("/etc/stbylong.sh");
+            if (!ret) 
+                printf ("STBYLONG - executing ...\n");            
+            else 
+                printf ("STBYLONG - problem kicking off STBYLONG ... not running. Error %d\n",ret);            
+        }
+        else if(newState == STBYSHORT)
+        {
+            // sleep for 30 mins, then wake, reboot
+            getTimeString (30, wakeTimeStr);
+            sprintf (buffer2, "%-s Wake@%-s", stateDesc[newState], wakeTimeStr);
+
+            CPhidgetTextLCD_setDisplayString (LCD, 1, buffer2);
+        
+            ret = system ("/etc/stbyshort.sh");
+            if (!ret) 
+                printf ("STBYSHORT - executing ...\n");            
+            else 
+                printf ("STBYSHORT - problem kicking off STBYSHORT ... not running. Error %d\n",ret);            
+        }
+        else if(newState == OVERRIDE)                
+        {
+            // stay up for 30 mins, then sleep, wake, reboot
+            time (&timenow);
+            tts = 1800 - (timenow - boottime);
+            printf ("%d to sleep\n", tts);
+
+            sprintf (buffer2, "%-s Time:%d", stateDesc[newState], tts/60);
+
+            CPhidgetTextLCD_setDisplayString (LCD, 1, buffer2);
+    
+            if (timenow > boottime + 1800) 
+            {
+                printf ("OVERRIDE - 30 mins expired ... switching to normal mode\n");
+                bootflag = "S";
+                printf ("Bootflag in case OVERRIDE %s \n", bootflag);
+            }            
+        }
+        else if(newState == SLEEP)
+        {
+            // We're running during night time - go to sleep
+            wakeTimeStr = SLEEPTIMEEND;
+            sprintf (buffer2, "%-s Wake@%-s", stateDesc[newState], wakeTimeStr);
+
+            CPhidgetTextLCD_setDisplayString (LCD, 1, buffer2);
+        
+            ret = system ("/etc/sleeprtc.sh");
+            if (!ret) 
+                printf ("SLEEPRTC - executing ...\n");            
+            else 
+                printf ("SLEEPRTC - problem kicking off SLEEPRTC ... not running. Error %d\n",ret);                    
+        }
+        else if(newState == UP)
+        {
+            // normal running here
+            // Nothing to do but continue loop
+        }
+        else
+        {
+            printf("Error invalid newState: (%d)\n",newState);    
+        }
+
+        fflush (stdout);
+        sleep (Sleep);
+
+    }//end while
+
+    closeCPhidget((CPhidgetHandle)IFK);
+    closeCPhidget((CPhidgetHandle)LCD);
+}
+
+#endif
--- a/stbylong.sh	Fri May 07 12:04:06 2010 +0100
+++ b/stbylong.sh	Thu May 13 18:16:50 2010 +0100
@@ -8,7 +8,7 @@
 #
 /usr/sbin/vbetool vbestate save > /tmp/videostate
 /usr/sbin/rtcwake -s 12800 -m mem
-/usr/sbin/vbetool vbestate restore < /temp/videostate
+/usr/sbin/vbetool vbestate restore < /tmp/videostate
 #
 echo "stbylong: Rebooting at `date`" >> /var/log/logrtc.log
 echo "S" > $BOOTFLAGFILE
--- a/stbyshort.sh	Fri May 07 12:04:06 2010 +0100
+++ b/stbyshort.sh	Thu May 13 18:16:50 2010 +0100
@@ -8,7 +8,7 @@
 #
 /usr/sbin/vbetool vbestate save > /tmp/videostate
 /usr/sbin/rtcwake -s 1800 -m mem
-/usr/sbin/vbetool vbestate restore < /temp/videostate
+/usr/sbin/vbetool vbestate restore < /tmp/videostate
 #
 echo "stbyshort: Rebooting at `date`" >> /var/log/logrtc.log
 echo "S" > $BOOTFLAGFILE