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.
--- 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