Fix everything
authorSam Moore <[email protected]>
Mon, 21 Oct 2013 09:36:46 +0000 (17:36 +0800)
committerSam Moore <[email protected]>
Mon, 21 Oct 2013 09:36:46 +0000 (17:36 +0800)
Jeremy helped*

* He did most of it.

22 files changed:
server/actuator.c
server/actuator.h
server/actuators/Makefile
server/actuators/pregulator.c [new file with mode: 0644]
server/actuators/pregulator.h [new file with mode: 0644]
server/actuators/relays.c [new file with mode: 0644]
server/actuators/relays.h [new file with mode: 0644]
server/bbb_pin.c
server/control.h
server/fastcgi.c
server/main.c
server/parameters
server/sensor.c
server/sensor.h
server/sensors/pressure.c
server/sensors/strain.c
server/sensors/strain.h
testing/MCTXWeb/public_html/control.html
testing/MCTXWeb/public_html/static/mctx.control.js
testing/MCTXWeb/public_html/static/mctx.graph.js
testing/MCTXWeb/public_html/stream.html [new file with mode: 0644]
testing/pygui/pygui.py

index 1c105db..617136e 100644 (file)
@@ -35,7 +35,7 @@ int Actuator_Add(const char * name, int user_id, SetFn set, InitFn init, CleanFn
        a->init = init; // Set init function
 
        a->sanity = sanity;
-
+       a->cleanup = cleanup;
        pthread_mutex_init(&(a->mutex), NULL);
 
        if (init != NULL)
@@ -51,16 +51,35 @@ int Actuator_Add(const char * name, int user_id, SetFn set, InitFn init, CleanFn
 
 
 /**
- * One off initialisation of *all* Actuators
+ * Initialisation of *all* Actuators
  */
-#include "actuators/ledtest.h"
-#include "actuators/filetest.h"
+#include "actuators/pregulator.h"
+#include "actuators/relays.h"
 void Actuator_Init()
 {
        //Actuator_Add("ledtest",0,  Ledtest_Set, NULL,NULL,NULL);
-       Actuator_Add("filetest", 0, Filetest_Set, Filetest_Init, Filetest_Cleanup, Filetest_Sanity, 0);
+       //Actuator_Add("filetest", 0, Filetest_Set, Filetest_Init, Filetest_Cleanup, Filetest_Sanity, 0);
+       Actuator_Add("pregulator", 0, Pregulator_Set, Pregulator_Init, Pregulator_Cleanup, Pregulator_Sanity, 0);
+       Actuator_Add("can_select", RELAY_CANSELECT, Relay_Set, Relay_Init, Relay_Cleanup, Relay_Sanity, 0);
+       Actuator_Add("can_enable", RELAY_CANENABLE, Relay_Set, Relay_Init, Relay_Cleanup, Relay_Sanity, 0);
+       Actuator_Add("main_pressure", RELAY_MAIN, Relay_Set, Relay_Init, Relay_Cleanup, Relay_Sanity, 1);
+}
+
+/**
+ * Deinitialise actuators
+ */
+void Actuator_Cleanup()
+{
+       for (int i = 0; i < g_num_actuators; ++i)
+       {
+               Actuator * a = g_actuators+i;
+               if (a->cleanup != NULL)
+                       a->cleanup(a->user_id);
+       }
+       g_num_actuators = 0;
 }
 
+
 /**
  * Sets the actuator to the desired mode. No checks are
  * done to see if setting to the desired mode will conflict with
@@ -143,8 +162,12 @@ void Actuator_SetMode(Actuator * a, ControlModes mode, void *arg)
  */
 void Actuator_SetModeAll(ControlModes mode, void * arg)
 {
+       if (mode == CONTROL_START)
+               Actuator_Init();
        for (int i = 0; i < g_num_actuators; i++)
                Actuator_SetMode(&g_actuators[i], mode, arg);
+       if (mode == CONTROL_STOP)
+               Actuator_Cleanup();
 }
 
 /**
@@ -173,7 +196,7 @@ void * Actuator_Loop(void * arg)
                // Currently does discrete steps after specified time intervals
 
                struct timespec wait;
-               DOUBLE_TO_TIMEVAL(a->control.stepsize, &wait);
+               DOUBLE_TO_TIMEVAL(a->control.stepwait, &wait);
                while (!a->control_changed && a->control.steps > 0 && a->activated)
                {
                        clock_nanosleep(CLOCK_MONOTONIC, 0, &wait, NULL);
@@ -381,7 +404,7 @@ void Actuator_Handler(FCGIContext * context, char * params)
        
                ActuatorControl c = {0.0, 0.0, 0.0, 0}; // Need to set default values (since we don't require them all)
                // sscanf returns the number of fields successfully read...
-               int n = sscanf(set, "%lf,%lf,%lf,%d", &(c.start), &(c.stepwait), &(c.stepsize), &(c.steps)); // Set provided values in order
+               int n = sscanf(set, "%lf_%lf_%lf_%d", &(c.start), &(c.stepwait), &(c.stepsize), &(c.steps)); // Set provided values in order
                if (n != 4)
                {
                        //      If the user doesn't provide all 4 values, the Actuator will get set *once* using the first of the provided values
index f818526..a5ac75b 100644 (file)
@@ -67,13 +67,14 @@ typedef struct
        /** Sanity check function **/
        SanityFn sanity;
        /** Cleanup function **/
-       CleanFn clean;
+       CleanFn cleanup;
        /** Last setting **/
        DataPoint last_setting;
        
 } Actuator;
 
 extern void Actuator_Init(); // One off initialisation of *all* Actuators
+extern void Actuator_Cleanup();
 
 extern void Actuator_SetModeAll(ControlModes mode, void *arg);
 extern void Actuator_SetMode(Actuator * a, ControlModes mode, void *arg);
index a2ba5dc..dfc247c 100644 (file)
@@ -3,7 +3,7 @@ CXX = gcc
 FLAGS = -std=c99 -Wall -pedantic -g -I../
 #-I/usr/include/opencv -I/usr/include/opencv2/highgui For OpenCV
 LIB = -lpthread
-OBJ = ledtest.o filetest.o
+OBJ = relays.o pregulator.o
 HEADERS = $(wildcard *.h)
 RM = rm -f
 
diff --git a/server/actuators/pregulator.c b/server/actuators/pregulator.c
new file mode 100644 (file)
index 0000000..f93c407
--- /dev/null
@@ -0,0 +1,32 @@
+#include "pregulator.h"
+#include "../bbb_pin.h"
+
+#define PREGULATOR_PWM ECAP0
+#define PREGULATOR_PERIOD 16666667
+
+/**
+ * Initiliase the pressure regulator
+ */
+bool Pregulator_Init(const char * name, int id)
+{
+       return PWM_Export(PREGULATOR_PWM) && PWM_Set(PREGULATOR_PWM, false, PREGULATOR_PERIOD, 0);
+}
+
+bool Pregulator_Cleanup(int id)
+{
+       if (!PWM_Set(PREGULATOR_PWM, false, PREGULATOR_PERIOD, 0))
+               return false;
+       PWM_Unexport(PREGULATOR_PWM);
+       return true;
+}
+
+bool Pregulator_Set(int id, double value)
+{
+       return PWM_Set(PREGULATOR_PWM, false, PREGULATOR_PERIOD, value*(PREGULATOR_PERIOD));
+}
+
+bool Pregulator_Sanity(int id, double value)
+{
+       return (value >= 0.0 && value <= 1.0);
+}
+
diff --git a/server/actuators/pregulator.h b/server/actuators/pregulator.h
new file mode 100644 (file)
index 0000000..c721140
--- /dev/null
@@ -0,0 +1,11 @@
+#ifndef _PREGULATOR
+
+#include "../common.h"
+
+extern bool Pregulator_Init(const char * name, int id);
+extern bool Pregulator_Cleanup(int id);
+extern bool Pregulator_Set(int id, double value);
+extern bool Pregulator_Sanity(int id, double value);
+
+
+#endif //_PREGULATOR
diff --git a/server/actuators/relays.c b/server/actuators/relays.c
new file mode 100644 (file)
index 0000000..dfa3d74
--- /dev/null
@@ -0,0 +1,48 @@
+#include "relays.h"
+#include "../log.h"
+
+#include "../bbb_pin.h"
+
+
+static int GetGPIO(int id)
+{
+       switch (id)
+       {
+               case RELAY_CANSELECT:
+                       return 14;
+               case RELAY_CANENABLE:
+                       return 115;
+               case RELAY_MAIN:
+                       return 112;
+       }
+       Fatal("Unknown id %d", id);
+       return 0;
+}
+
+bool Relay_Init(const char * name, int id)
+{
+       if (!GPIO_Export(GetGPIO(id)))
+               return false;
+       return GPIO_Set(GetGPIO(id), false);
+}
+
+bool Relay_Cleanup(int id)
+{
+       bool err = GPIO_Set(GetGPIO(id), false);
+       GPIO_Unexport(GetGPIO(id));
+       return err;
+}
+
+bool Relay_Set(int id, double value)
+{
+       bool set = (bool)value;
+       return GPIO_Set(GetGPIO(id), set);
+}
+
+bool Relay_Sanity(int id, double value)
+{
+       //bool set = (bool)value;
+       //TODO: Make a more sane sanity check
+       return true;
+       
+}
diff --git a/server/actuators/relays.h b/server/actuators/relays.h
new file mode 100644 (file)
index 0000000..dcffbf9
--- /dev/null
@@ -0,0 +1,18 @@
+#ifndef _RELAY_H
+#define _RELAY_H
+
+#include "../common.h"
+
+typedef enum
+{
+       RELAY_CANSELECT,
+       RELAY_CANENABLE,
+       RELAY_MAIN
+} RelayID;
+
+extern bool Relay_Init(const char * name, int id);
+extern bool Relay_Set(int id, double value);
+extern bool Relay_Sanity(int id, double value);
+extern bool Relay_Cleanup(int id);
+
+#endif //_RELAY_H
index 2ffc9e5..bd31365 100644 (file)
@@ -501,7 +501,8 @@ bool ADC_Read(int id, int *value)
 
        if (pread(g_adc[id].fd_value, adc_str, ADC_DIGITS-1, 0) == -1)
        {
-               AbortBool("ADC %d read failed: %s", id, strerror(errno));
+               //AbortBool("ADC %d read failed: %s", id, strerror(errno));
+               return false;
        }
 
        *value = strtol(adc_str, NULL, 10);
index 7081c3f..0dfdc47 100644 (file)
@@ -18,6 +18,8 @@ typedef enum ControlModes {
 /** The same as INVALID_CHARACTERS, except escaped for use in JSON strings **/
 #define INVALID_CHARACTERS_JSON "\\\"*/:<>?\\\\|. "
 
+#define NOAUTH_USERNAME "_anonymous_noauth"
+
 extern void Control_Handler(FCGIContext *context, char *params);
 extern const char* Control_SetMode(ControlModes desired_mode, void * arg);
 extern ControlModes Control_GetMode();
index af92efd..75863c1 100644 (file)
@@ -46,8 +46,7 @@ static void IdentifyHandler(FCGIContext *context, char *params)
        FCGI_BeginJSON(context, STATUS_OK);
        FCGI_JSONPair("description", "MCTX3420 Server API (2013)");
        FCGI_JSONPair("build_date", __DATE__ " " __TIME__);
-       struct timespec t;
-       t.tv_sec = 0; t.tv_nsec = 0;
+       struct timespec t = {0};
        clock_getres(CLOCK_MONOTONIC, &t);
        FCGI_JSONDouble("clock_getres", TIMEVAL_TO_DOUBLE(t));
        FCGI_JSONLong("api_version", API_VERSION);
@@ -65,7 +64,9 @@ static void IdentifyHandler(FCGIContext *context, char *params)
                        if (i > 0) {
                                FCGI_JSONValue(",\n\t\t");
                        }
-                       FCGI_JSONValue("\"%d\" : \"%s\"", i, Sensor_GetName(i)); 
+                       DataPoint d = Sensor_LastData(i);
+                       FCGI_JSONValue("\"%d\" : {\"name\" : \"%s\", \"value\" : [%f,%f] }", 
+                               i, Sensor_GetName(i), d.time_stamp, d.value); 
                }
                FCGI_JSONValue("\n\t}");
        }
@@ -76,7 +77,9 @@ static void IdentifyHandler(FCGIContext *context, char *params)
                        if (i > 0) {
                                FCGI_JSONValue(",\n\t\t");
                        }
-                       FCGI_JSONValue("\"%d\" : \"%s\"", i, Actuator_GetName(i)); 
+
+                       DataPoint d = Sensor_LastData(i);
+                       FCGI_JSONValue("\"%d\" : {\"name\" : \"%s\", \"value\" : [%f, %f] }", i, Actuator_GetName(i), d.time_stamp, d.value); 
                }
                FCGI_JSONValue("\n\t}");
        }
@@ -591,13 +594,22 @@ void * FCGI_RequestLoop (void *data)
                
                if (module_handler) 
                {
-                       if (g_options.auth_method != AUTH_NONE && module_handler != Login_Handler && module_handler != IdentifyHandler && module_handler)
+                       if (module_handler != Login_Handler && module_handler != IdentifyHandler && module_handler)
                        //if (false) // Testing
                        {
                                if (!FCGI_HasControl(&context))
                                {
-                                       FCGI_RejectJSON(&context, "Please login. Invalid control key.");
-                                       continue;       
+                                       if (g_options.auth_method == AUTH_NONE)
+                                       {       //:(
+                                               Log(LOGWARN, "Locking control (no auth!)");
+                                               FCGI_LockControl(&context, NOAUTH_USERNAME, USER_ADMIN);
+                                               FCGI_SendControlCookie(&context, true);
+                                       }
+                                       else
+                                       {
+                                               FCGI_RejectJSON(&context, "Please login. Invalid control key.");
+                                               continue;
+                                       }
                                }
 
                                //Escape all special characters.
index fadcd3a..a4b7c5a 100644 (file)
@@ -123,7 +123,7 @@ void Cleanup()
 {
        Log(LOGDEBUG, "Begin cleanup.");
        Sensor_Cleanup();
-       //Actuator_Cleanup();
+       Actuator_Cleanup();
        Log(LOGDEBUG, "Finish cleanup.");
 }
 
@@ -199,23 +199,22 @@ int main(int argc, char ** argv)
 
        
 
-       Sensor_Init();
-       Actuator_Init();
        Pin_Init();
        
        // Try and start things
        
-       const char *ret;
-       if ((ret = Control_SetMode(CONTROL_START, "test")) != NULL)
-               Fatal("Control_SetMode failed with '%s'", ret);
+       //const char *ret;
+       //if ((ret = Control_SetMode(CONTROL_START, "test")) != NULL)
+       //      Fatal("Control_SetMode failed with '%s'", ret);
        
 
        // run request thread in the main thread
        FCGI_RequestLoop(NULL);
 
        
-       if ((ret = Control_SetMode(CONTROL_STOP, "test")) != NULL)
-               Fatal("Control_SetMode failed with '%s'", ret);
+       Control_SetMode(CONTROL_STOP, NULL);
+       //if ((ret = Control_SetMode(CONTROL_STOP, "test")) != NULL)
+       //      Fatal("Control_SetMode failed with '%s'", ret);
        
        //Sensor_StopAll();
        //Actuator_StopAll();
index da48239..26e2892 100644 (file)
@@ -23,7 +23,7 @@ pin_test="0"
 #auth_uri="ldap://192.168.1.1"
 #auth_uri="ldaps://ldap.pheme.uwa.edu.au" #UWA
 #auth_uri="/etc/shadow"
-auth_uri="shadow"
+#auth_uri="shadow"
 
 # Set to the dn of the LDAP server
 ldap_base_dn="ou=People,dc=daedalus" # Testing
@@ -31,4 +31,5 @@ ldap_base_dn="ou=People,dc=daedalus" # Testing
 
 
 ## OPTIONS TO BE PASSED TO SERVER; DO NOT EDIT
-parameters="-v $verbosity -p $pin_test -A $auth_uri -d $ldap_base_dn"
+parameters="-v $verbosity -p $pin_test"
+# -A $auth_uri -d $ldap_base_dn"
index ae5cdf4..d146905 100644 (file)
@@ -47,7 +47,7 @@ int Sensor_Add(const char * name, int user_id, ReadFn read, InitFn init, CleanFn
        s->init = init; // Set init function
 
        // Start by averaging values taken over a second
-       DOUBLE_TO_TIMEVAL(1e-4, &(s->sample_time));
+       DOUBLE_TO_TIMEVAL(1e-3, &(s->sample_time));
        s->averages = 1;
        s->num_read = 0;
 
@@ -62,6 +62,8 @@ int Sensor_Add(const char * name, int user_id, ReadFn read, InitFn init, CleanFn
 
        s->current_data.time_stamp = 0;
        s->current_data.value = 0;
+       s->averaged_data.time_stamp = 0;
+       s->averaged_data.value = 0;
        return g_num_sensors;
 }
 
@@ -75,16 +77,16 @@ int Sensor_Add(const char * name, int user_id, ReadFn read, InitFn init, CleanFn
 #include "sensors/pressure.h"
 void Sensor_Init()
 {
-       Sensor_Add("cpu_stime", RESOURCE_CPU_SYS, Resource_Read, NULL, NULL, NULL);     
-       Sensor_Add("cpu_utime", RESOURCE_CPU_USER, Resource_Read, NULL, NULL, NULL);    
-       //Sensor_Add("pressure_high0", PRES_HIGH0, Pressure_Read, Pressure_Init, Pressure_Cleanup, NULL);
-       //Sensor_Add("pressure_high1", PRES_HIGH1, Pressure_Read, Pressure_Init, Pressure_Cleanup, NULL);
-       //Sensor_Add("pressure_low0", PRES_LOW0, Pressure_Read, Pressure_Init, Pressure_Cleanup, NULL);
+       //Sensor_Add("cpu_stime", RESOURCE_CPU_SYS, Resource_Read, NULL, NULL, NULL);   
+       //Sensor_Add("cpu_utime", RESOURCE_CPU_USER, Resource_Read, NULL, NULL, NULL);  
+       Sensor_Add("pressure_high0", PRES_HIGH0, Pressure_Read, Pressure_Init, Pressure_Cleanup, NULL);
+       Sensor_Add("pressure_high1", PRES_HIGH1, Pressure_Read, Pressure_Init, Pressure_Cleanup, NULL);
+       Sensor_Add("pressure_low0", PRES_LOW0, Pressure_Read, Pressure_Init, Pressure_Cleanup, NULL);
        //Sensor_Add("../testing/count.py", 0, Piped_Read, Piped_Init, Piped_Cleanup, 1e50,-1e50,1e50,-1e50);
-       //Sensor_Add("strain0", STRAIN0, Strain_Read, Strain_Init, 5000,0,5000,0);
-       //Sensor_Add("strain1", STRAIN1, Strain_Read, Strain_Init, 5000,0,5000,0);
-       //Sensor_Add("strain2", STRAIN2, Strain_Read, Strain_Init, 5000,0,5000,0);
-       //Sensor_Add("strain3", STRAIN3, Strain_Read, Strain_Init, 5000,0,5000,0);
+       Sensor_Add("strain0", STRAIN0, Strain_Read, Strain_Init, Strain_Cleanup, Strain_Sanity);
+       Sensor_Add("strain1", STRAIN1, Strain_Read, Strain_Init, Strain_Cleanup, Strain_Sanity);
+       Sensor_Add("strain2", STRAIN2, Strain_Read, Strain_Init, Strain_Cleanup, Strain_Sanity);
+       Sensor_Add("strain3", STRAIN3, Strain_Read, Strain_Init, Strain_Cleanup, Strain_Sanity);
        //Sensor_Add("pressure0", PRESSURE0, Pressure_Read, Pressure_Init, 5000,0,5000,0);
        //Sensor_Add("pressure1", PRESSURE1, Pressure_Read, Pressure_Init, 5000,0,5000,0);
        //Sensor_Add("pressure_feedback", PRESSURE_FEEDBACK, Pressure_Read, Pressure_Init, 5000,0,5000,0);
@@ -103,6 +105,7 @@ void Sensor_Cleanup()
                if (s->cleanup != NULL)
                        s->cleanup(s->user_id);
        }
+       g_num_sensors = 0;
 }
 
 /**
@@ -183,8 +186,12 @@ void Sensor_SetMode(Sensor * s, ControlModes mode, void * arg)
  */
 void Sensor_SetModeAll(ControlModes mode, void * arg)
 {
+       if (mode == CONTROL_START)
+               Sensor_Init();
        for (int i = 0; i < g_num_sensors; i++)
                Sensor_SetMode(&g_sensors[i], mode, arg);
+       if (mode == CONTROL_STOP)
+               Sensor_Cleanup();
 }
 
 
@@ -201,38 +208,40 @@ void * Sensor_Loop(void * arg)
        // Until the sensor is stopped, record data points
        while (s->activated)
        {
-               DataPoint d;
-               d.value = 0;
-               bool success = s->read(s->user_id, &(d.value));
+               
+               bool success = s->read(s->user_id, &(s->current_data.value));
 
                struct timespec t;
                clock_gettime(CLOCK_MONOTONIC, &t);
-               d.time_stamp = TIMEVAL_DIFF(t, *Control_GetStartTime());        
+               s->current_data.time_stamp = TIMEVAL_DIFF(t, *Control_GetStartTime());  
                
                if (success)
                {
                        if (s->sanity != NULL)
                        {
-                               if (!s->sanity(s->user_id, d.value))
+                               if (!s->sanity(s->user_id, s->current_data.value))
                                {
                                        Fatal("Sensor %s (%d,%d) reads unsafe value", s->name, s->id, s->user_id);
                                }
                        }
-                       s->current_data.time_stamp += d.time_stamp;
-                       s->current_data.value += d.value;
+                       s->averaged_data.time_stamp += s->current_data.time_stamp;
+                       s->averaged_data.value = s->current_data.value;
                        
                        if (++(s->num_read) >= s->averages)
                        {
-                               s->current_data.time_stamp /= s->averages;
-                               s->current_data.value /= s->averages;
-                               Data_Save(&(s->data_file), &(s->current_data), 1); // Record it
+                               s->averaged_data.time_stamp /= s->averages;
+                               s->averaged_data.value /= s->averages;
+                               Data_Save(&(s->data_file), &(s->averaged_data), 1); // Record it
                                s->num_read = 0;
-                               s->current_data.time_stamp = 0;
-                               s->current_data.value = 0;
+                               s->averaged_data.time_stamp = 0;
+                               s->averaged_data.value = 0;
                        }
                }
                else
-                       Log(LOGWARN, "Failed to read sensor %s (%d,%d)", s->name, s->id,s->user_id);
+               {
+                       // Silence because strain sensors fail ~50% of the time :S
+                       //Log(LOGWARN, "Failed to read sensor %s (%d,%d)", s->name, s->id,s->user_id);
+               }
 
 
                clock_nanosleep(CLOCK_MONOTONIC, 0, &(s->sample_time), NULL);
@@ -408,5 +417,10 @@ const char * Sensor_GetName(int id)
        return g_sensors[id].name;
 }
 
+DataPoint Sensor_LastData(int id)
+{
+       Sensor * s = &(g_sensors[id]);
+       return s->current_data;
+}
 
 
index 0188361..3de48e0 100644 (file)
@@ -61,6 +61,9 @@ typedef struct
        int averages;
        /** Current data **/
        DataPoint current_data;
+
+       /** Summed data **/
+       DataPoint averaged_data;
        /** Number of points read so far before applying average **/
        int num_read;
 
@@ -82,6 +85,8 @@ extern Sensor * Sensor_Identify(const char * str); // Identify a Sensor from a s
 
 extern void Sensor_Handler(FCGIContext *context, char * params); // Handle a FCGI request for Sensor data
 
+extern DataPoint Sensor_LastData(int id);
+
 extern const char * Sensor_GetName(int id);
 
 
index 61cdbcf..29b8d28 100644 (file)
@@ -40,6 +40,9 @@ double Pressure_Callibrate(int id, int adc)
 {
        //double voltage = ADC_TO_VOLTS(adc); // convert reading to voltage
 
+       return (double)adc;
+
+       //TODO: Fix this
        switch (id)
        {
                case PRES_HIGH0:
index 9492de7..4278d6c 100644 (file)
@@ -68,6 +68,24 @@ bool Strain_Init(const char * name, int id)
        return true;
 }
 
+bool Strain_Cleanup(int id)
+{
+       static bool kill_adc = false;
+       if (!kill_adc)
+       {
+               kill_adc = true;
+               ADC_Unexport(STRAIN_ADC);
+       }
+       int gpio_num = Strain_To_GPIO(id);
+       GPIO_Unexport(gpio_num);
+       return true;
+}
+
+bool Strain_Sanity(int id, double value)
+{
+       return true;
+}
+
 /**
  * Read from a Strain gauge
  * @param id - The strain gauge to read
index 1afb625..21b926e 100644 (file)
@@ -19,4 +19,7 @@ extern bool Strain_Init(const char * name, int id);
 // Read from a strain gauge
 extern bool Strain_Read(int id, double * value);
 
+extern bool Strain_Cleanup(int id);
+extern bool Strain_Sanity(int id, double value);
+
 #endif //_STRAIN_H
index 412f7f8..7d7b9ad 100644 (file)
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
-<html>
-  <head>
-    <title>MCTX3420 Web Interface</title>
-    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
-    <!--[if lte IE 8]>
-      <script language="javascript" type="text/javascript" src="static/excanvas.min.js"></script>
-    <![endif]-->
-    <script type="text/javascript" src="static/jquery-1.10.1.min.js"></script>
-    <script type="text/javascript" src="static/jquery.flot.min.js"></script>
-    <script type="text/javascript" src="static/mctx.gui.js"></script>
-    <script type="text/javascript" src="static/mctx.control.js"></script>
-    
-    <link rel="stylesheet" type="text/css" href="static/style.css">
-    <link rel="stylesheet" type="text/css" href="static/nav-menu.css">
-    <script type="text/javascript">
-      runBeforeLoad().done(function () {
-        $(document).ready(function () {
-          $("form").submit(function () { //Prevent form submit globally
-            return false;
-          })
-          
-          //Set the status updated
-          $("#state-exp").setStatusUpdater();
-          
-          //Set the logic for the start controls
-          $("#start-controls").submit(function () {
-            var start = $("#start-controls input[type='button']");
-            var force = $("#start-controls input[name='start_force']");
-            
-            $(this).startExperiment(start, $("#experiment_name").val(), 
-                      force.is(":checked"), $("#start-result"));
-            force.prop("checked", false);
-          });
-          
-          //Set the logic for the stop button
-          $("#experiment-stop").click(function () {
-            $(this).stopExperiment($("#stop-status"));
-          });
-          
-          //Set the logic for the pressure controls
-          $("#pressure-controls").submit(function () {
-            var pressure = {
-              set : $("#pressure-set").val(),
-              step : $("#pressure-stepsize").val(),
-              wait : $("#pressure-stepwait").val(),
-              count : $("#pressure-stepcount").val()
-            };   
-            $(this).setPressure(pressure, $("#pressure-result"));
-          });
-          
-          //Set logic for sensor sample rate thing
-          $("#sensor-select").loadSensorList($("#samplerate-result"));
-          $("#samplerate-controls").submit(function () {
-            setSampleRate($("#sensor-select option:selected").val(), 
-                          $("#sensor-set").val(), $("#samplerate-result"));
-          });
-       });       
-      }).fail(function () {
-        $(document).ready(function () {
-         $("#state-exp").text("Connection failure").parent().addClass("fail");
-       });  
-      });
-    </script>
-  </head>
-  
-  <body>
-    <div id="header-wrap">
-      <div id="header">
-        <div id="leftnav">
-          <a href="http://www.uwa.edu.au/" target="_blank">
-            <img alt = "The University of Western Australia"
-            src="static/uwacrest-text.png">
-          </a>
-          <span id="title">Exploding Cans</span>
-        </div>
-        <div id="rightnav">
-          <span id="welcome-container">
-          </span>
-          <span id="date">
-            <script type="text/javascript">getDate();</script>
-          </span>
-          <div id="logout-container">
-            <form action="#">
-              <div>
-                <input type="button" id="logout" value="Logout">
-              </div>
-            </form>
-          </div>
-        </div>
-        <div class="clear"></div>
-      </div>
-    </div>
-    <!-- End header -->
-    
-    <div id="content-wrap">
-      <noscript>
-        <div class="widget centre">
-          <div class="title">JavaScript required</div>
-          This website requires JavaScript to function correctly.
-          Please enable JavaScript to use this site.
-        </div>
-      </noscript>
-
-      <div id="content">
-        <div class="widget" id="sidebar-show">&gt;</div>
-        <div id="sidebar">
-          <div class="widget">
-            <div id="sidebar-hide">&lt;</div>
-            <div class="title">Navigation menu</div>
-            <div id="sidebar-menu" class="nav-menu">
-              <ul>
-                <li><a href="index.html"><span>Home</span></a></li>
-                <li><a href="control.html"><span>Experiment control</span></a></li>
-                <li><a href="graph.html"><span>Experiment graphs</span></a></li>
-                <li><a href="data.html"><span>Experiment data</span></a></li>
-                <li><a href="pintest.html"><span>Pin debugging</span></a></li>
-                <li class="last"><a href="help.html"><span>Help</span></a></li>
-              </ul>
-            </div>
-          </div>
-        </div>
-        <!-- End sidebar -->
-
-        <div id="main">
-          <div class="widget">
-            <div class="title">Experiment Overview</div>
-            <table class="horizontal medium">
-              <tr id="state-exp-r">
-                <th>Experiment state</th>
-                <td id="state-exp"></td>
-                <td style="text-align: right;">
-                  <input id="experiment-stop" type="button" value="Stop">
-                </td>
-              </tr>
-            </table>
-            <div id="stop-status">
-              &nbsp;
-            </div>
-            
-            <div class="sub-title">Error and warning messages</div>
-            <textarea id="errorlog" wrap="off" rows="4" cols="30" readonly>
-            </textarea>
-          </div>
-          
-          <div id="start-widget" class="widget">
-            <div class="title centre">Start an experiment</div>
-            <form id="start-controls" class="nice" action="#">
-              <p>
-                <label for="experiment_name">Experiment name</label>
-                <input id="experiment_name" type="text">
-                
-                <label for="start_force">Overwrite existing</label>
-                <input type="checkbox" name="start_force" id="start_force">
-              </p>
-              <p id="start-result">
-                &nbsp;
-              </p>
-              <p class="centre">
-                <input type="submit" name="start_strain" value="Strain test">
-                <input type="submit" name="start_explode" value="Explode test">                
-              </p>
-            </form>
-          </div>
-          
-          <div id="pressure-widget" class="widget">            
-            <form id="pressure-controls" action="#" class="nice clear">
-              <table>
-                <tr>
-                  <td><label for="pressure-set">Starting pressure (kPa)</label></td>
-                  <td><label for="pressure-stepsize">Pressure step size (kPa)</label></td>
-                </tr>
-                <tr>
-                  <td><input id="pressure-set" type="text"></td>
-                  <td><input id="pressure-stepsize" type="text"></td>
-                </tr>
-                <tr>
-                  <td><label for="pressure-stepcount">Number of steps to make</label></td>
-                  <td><label for="pressure-stepwait">Wait time between steps (s)</label></td>
-                </tr>
-                <tr>
-                  <td><input id="pressure-stepcount" type="text"></td>
-                  <td><input id="pressure-stepwait" type="text"></td>
-                </tr>
-              </table>
-              <p class="left" id="pressure-result">
-                &nbsp;
-              </p>
-              <p class="right">
-                <input type="submit" value="Set pressure">
-              </p>
-            </form>
-            
-            <form id="samplerate-controls" action="#" class="nice clear">
-              <table>
-                <tr>
-                  <td><label for="sensor-select">Select a sensor</label></td>
-                  <td><label for="sensor-set">Set sampling rate (s)</label></td>
-                </tr>
-                <tr>
-                  <td><select id="sensor-select" style="width:100%;"></select></td>
-                  <td><input id="sensor-set" type="text"></td>
-                </tr>
-              </table>
-              <p class="left" id="samplerate-result">
-                &nbsp;
-              </p>
-              <p class="right">
-                <input type="submit" value="Set sampling rate">
-              </p>
-            </form>
-          </div>
-          
-          <div id="stats-widget" class="widget">
-            <form id="stats" action="#" class="nice clear">
-              <table>
-                <tr>
-                  <td><label for="stats-mainspressure">Mains pressure (kPa)</label></td>
-                  <td><label for="stats-canpressure">Can pressure (kPa)</label></td>
-                </tr>
-                <tr>
-                  <td><input id="stats-mainspressure" type="text" readonly></td>
-                  <td><input id="stats-canpressure" type="text" readonly></td>
-                </tr>
-                <tr class="stats-strain">
-                  <td><label for="stats-strain1">Central hoop strain</label></td>
-                  <td><label for="stats-strain2">Central longitudinal strain</label></td>
-                </tr>
-                <tr class="stats-strain">
-                  <td><input id="stats-strain1" type="text" readonly></td>
-                  <td><input id="stats-strain2" type="text" readonly></td>
-                </tr>
-                <tr class="stats-strain">
-                  <td><label for="stats-strain3">End hoop strain</label></td>
-                  <td><label for="stats-strain4">End longitudinal strain</label></td>
-                </tr>
-                <tr class="stats-strain">
-                  <td><input id="stats-strain3" type="text" readonly></td>
-                  <td><input id="stats-strain4" type="text" readonly></td>
-                </tr>
-                <tr class="stats-strain">
-                  <td><label for="stats-dilatometer">Dilatometer reading</label></td>
-                  <td><label for="stats-dilatometer">Camera feed</label></td>
-                </tr>
-                <tr class="stats-strain">
-                  <td><input id="stats-dilatometer" type="text" readonly></td>
-                  <td><a href="#">Link</a></td>
-                </tr>
-              </table>
-            </form>
-          </div>
-          
-        </div>
-        <!-- End main content -->
-      </div>
-    </div>
-  </body>
-</html>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">\r
+<html>\r
+  <head>\r
+    <title>MCTX3420 Web Interface</title>\r
+    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">\r
+    <!--[if lte IE 8]>\r
+      <script language="javascript" type="text/javascript" src="static/excanvas.min.js"></script>\r
+    <![endif]-->\r
+    <script type="text/javascript" src="static/jquery-1.10.1.min.js"></script>\r
+    <script type="text/javascript" src="static/jquery.flot.min.js"></script>\r
+    <script type="text/javascript" src="static/mctx.gui.js"></script>\r
+    <script type="text/javascript" src="static/mctx.control.js"></script>\r
+    \r
+    <link rel="stylesheet" type="text/css" href="static/style.css">\r
+    <link rel="stylesheet" type="text/css" href="static/nav-menu.css">\r
+    <script type="text/javascript">\r
+      runBeforeLoad().done(function () {\r
+        $(document).ready(function () {\r
+          $("form").submit(function () { //Prevent form submit globally\r
+            return false;\r
+          });\r
+          \r
+          //Set the status updated\r
+          $("#state-exp").setStatusUpdater();\r
+          \r
+          //Set the logic for the start controls\r
+          $("#start-controls input[type='button']").click(function () {\r
+            var start = $("#start-controls input[type='button']");\r
+            var force = $("#start-controls input[name='start_force']");\r
+            \r
+            $(this).startExperiment(start, $("#experiment_name").val(), \r
+                      force.is(":checked"), $("#start-result"));\r
+            force.prop("checked", false);\r
+          });\r
+          \r
+          //Set the logic for the stop button\r
+          $("#experiment-stop").click(function () {\r
+            $(this).stopExperiment($("#stop-status"));\r
+          });\r
+          \r
+          //Set the logic for the pressure controls\r
+          $("#pressure-controls").submit(function () {\r
+            var pressure = {\r
+              set : $("#pressure-set").val(),\r
+              step : $("#pressure-stepsize").val(),\r
+              wait : $("#pressure-stepwait").val(),\r
+              count : $("#pressure-stepcount").val()\r
+            };   \r
+            $(this).setPressure(pressure, $("#pressure-result"));\r
+          });\r
+          \r
+          $("#samplerate-controls").submit(function () {\r
+            setSampleRate($("#sensor-select option:selected").val(), \r
+                          $("#sensor-set").val(), $("#samplerate-result"));\r
+          });\r
+       });       \r
+      }).fail(function () {\r
+        $(document).ready(function () {\r
+         $("#state-exp").text("Connection failure").parent().addClass("fail");\r
+       });  \r
+      });\r
+    </script>\r
+  </head>\r
+  \r
+  <body>\r
+    <div id="header-wrap">\r
+      <div id="header">\r
+        <div id="leftnav">\r
+          <a href="http://www.uwa.edu.au/" target="_blank">\r
+            <img alt = "The University of Western Australia"\r
+            src="static/uwacrest-text.png">\r
+          </a>\r
+          <span id="title">Exploding Cans</span>\r
+        </div>\r
+        <div id="rightnav">\r
+          <span id="welcome-container">\r
+          </span>\r
+          <span id="date">\r
+            <script type="text/javascript">getDate();</script>\r
+          </span>\r
+          <div id="logout-container">\r
+            <form action="#">\r
+              <div>\r
+                <input type="button" id="logout" value="Logout">\r
+              </div>\r
+            </form>\r
+          </div>\r
+        </div>\r
+        <div class="clear"></div>\r
+      </div>\r
+    </div>\r
+    <!-- End header -->\r
+    \r
+    <div id="content-wrap">\r
+      <noscript>\r
+        <div class="widget centre">\r
+          <div class="title">JavaScript required</div>\r
+          This website requires JavaScript to function correctly.\r
+          Please enable JavaScript to use this site.\r
+        </div>\r
+      </noscript>\r
+\r
+      <div id="content">\r
+        <div class="widget" id="sidebar-show">&gt;</div>\r
+        <div id="sidebar">\r
+          <div class="widget">\r
+            <div id="sidebar-hide">&lt;</div>\r
+            <div class="title">Navigation menu</div>\r
+            <div id="sidebar-menu" class="nav-menu">\r
+              <ul>\r
+                <li><a href="index.html"><span>Home</span></a></li>\r
+                <li><a href="control.html"><span>Experiment control</span></a></li>\r
+                <li><a href="graph.html"><span>Experiment graphs</span></a></li>\r
+                <li><a href="data.html"><span>Experiment data</span></a></li>\r
+                <li><a href="pintest.html"><span>Pin debugging</span></a></li>\r
+                <li class="last"><a href="help.html"><span>Help</span></a></li>\r
+              </ul>\r
+            </div>\r
+          </div>\r
+        </div>\r
+        <!-- End sidebar -->\r
+\r
+        <div id="main">\r
+          <div class="widget">\r
+            <div class="title">Experiment Overview</div>\r
+            <table class="horizontal medium">\r
+              <tr id="state-exp-r">\r
+                <th>Experiment state</th>\r
+                <td id="state-exp"></td>\r
+                <td style="text-align: right;">\r
+                  <input id="experiment-stop" type="button" value="Stop">\r
+                </td>\r
+              </tr>\r
+            </table>\r
+            <div id="stop-status">\r
+              &nbsp;\r
+            </div>\r
+            \r
+            <div class="sub-title">Error and warning messages</div>\r
+            <textarea id="errorlog" wrap="off" rows="4" cols="30" readonly>\r
+            </textarea>\r
+          </div>\r
+          \r
+          <div id="start-widget" class="widget">\r
+            <div class="title centre">Start an experiment</div>\r
+            <form id="start-controls" class="nice" action="#">\r
+              <p>\r
+                <label for="experiment_name">Experiment name</label>\r
+                <input id="experiment_name" type="text">\r
+                \r
+                <label for="start_force">Overwrite existing</label>\r
+                <input type="checkbox" name="start_force" id="start_force">\r
+              </p>\r
+              <p id="start-result">\r
+                &nbsp;\r
+              </p>\r
+              <p class="centre">\r
+                <input type="button" name="start_strain" value="Strain test">\r
+                <input type="button" name="start_explode" value="Explode test">                \r
+              </p>\r
+            </form>\r
+          </div>\r
+          \r
+          <div id="pressure-widget" class="widget">            \r
+            <form id="pressure-controls" action="#" class="nice clear">\r
+              <table>\r
+                <tr>\r
+                  <td><label for="pressure-set">Starting pressure (kPa)</label></td>\r
+                  <td><label for="pressure-stepsize">Pressure step size (kPa)</label></td>\r
+                </tr>\r
+                <tr>\r
+                  <td><input id="pressure-set" type="text"></td>\r
+                  <td><input id="pressure-stepsize" type="text"></td>\r
+                </tr>\r
+                <tr>\r
+                  <td><label for="pressure-stepcount">Number of steps to make</label></td>\r
+                  <td><label for="pressure-stepwait">Wait time between steps (s)</label></td>\r
+                </tr>\r
+                <tr>\r
+                  <td><input id="pressure-stepcount" type="text"></td>\r
+                  <td><input id="pressure-stepwait" type="text"></td>\r
+                </tr>\r
+              </table>\r
+              <p class="left" id="pressure-result">\r
+                &nbsp;\r
+              </p>\r
+              <p class="right">\r
+                <input type="submit" value="Set pressure">\r
+              </p>\r
+            </form>\r
+            \r
+            <form id="samplerate-controls" action="#" class="nice clear">\r
+              <table>\r
+                <tr>\r
+                  <td><label for="sensor-select">Select a sensor</label></td>\r
+                  <td><label for="sensor-set">Set sampling rate (s)</label></td>\r
+                </tr>\r
+                <tr>\r
+                  <td><select id="sensor-select" style="width:100%;"></select></td>\r
+                  <td><input id="sensor-set" type="text"></td>\r
+                </tr>\r
+              </table>\r
+              <p class="left" id="samplerate-result">\r
+                &nbsp;\r
+              </p>\r
+              <p class="right">\r
+                <input type="submit" value="Set sampling rate">\r
+              </p>\r
+            </form>\r
+          </div>\r
+          \r
+          <div id="stats-widget" class="widget">\r
+            <form id="stats" action="#" class="nice clear">\r
+              <table>\r
+                <tr>\r
+                  <td><label for="stats-mainspressure">Mains pressure (kPa)</label></td>\r
+                  <td><label for="stats-canpressure">Can pressure (kPa)</label></td>\r
+                </tr>\r
+                <tr>\r
+                  <td><input id="stats-mainspressure" type="text" readonly></td>\r
+                  <td><input id="stats-canpressure" type="text" readonly></td>\r
+                </tr>\r
+                <tr class="stats-strain">\r
+                  <td><label for="stats-strain1">Central hoop strain</label></td>\r
+                  <td><label for="stats-strain2">Central longitudinal strain</label></td>\r
+                </tr>\r
+                <tr class="stats-strain">\r
+                  <td><input id="stats-strain1" type="text" readonly></td>\r
+                  <td><input id="stats-strain2" type="text" readonly></td>\r
+                </tr>\r
+                <tr class="stats-strain">\r
+                  <td><label for="stats-strain3">End hoop strain</label></td>\r
+                  <td><label for="stats-strain4">End longitudinal strain</label></td>\r
+                </tr>\r
+                <tr class="stats-strain">\r
+                  <td><input id="stats-strain3" type="text" readonly></td>\r
+                  <td><input id="stats-strain4" type="text" readonly></td>\r
+                </tr>\r
+                <tr class="stats-strain">\r
+                  <td><label for="stats-dilatometer">Dilatometer reading</label></td>\r
+                  <td><label for="stats-dilatometer">Camera feed</label></td>\r
+                </tr>\r
+                <tr class="stats-strain">\r
+                  <td><input id="stats-dilatometer" type="text" readonly></td>\r
+                  <td><a href="#">Link</a></td>\r
+                </tr>\r
+              </table>\r
+            </form>\r
+          </div>\r
+          \r
+        </div>\r
+        <!-- End main content -->\r
+      </div>\r
+    </div>\r
+  </body>\r
+</html>\r
index 1d5c744..de45e61 100644 (file)
@@ -47,6 +47,7 @@ function setSampleRate(id, val, result) {
 
 $.fn.loadSensorList = function (result, input) {
   var select = this;
+  select.empty(); //Reset list\r
   
   $.ajax({
     url : mctx.api + 'identify',
@@ -56,7 +57,7 @@ $.fn.loadSensorList = function (result, input) {
       return;
     }
     for (var id in data.sensors) {
-      var option = $("<option/>", {value : id, text : data.sensors[id]});
+      var option = $("<option/>", {value : id, text : data.sensors[id].name});
       select.append(option);
     }
   });
@@ -103,7 +104,9 @@ $.fn.setStatusUpdater = function () {
           fail = true;
       }
       
-      if (data.control_state_id !== mctx.control.state) {      
+      if (data.control_state_id !== mctx.control.state) {   \r
+        //Set logic for sensor sample rate thing\r
+        $("#sensor-select").loadSensorList($("#samplerate-result"));      
         toggleControls(running);
         $(result).text(text);
         if (fail) {
@@ -129,6 +132,8 @@ $.fn.setStatusUpdater = function () {
 
 $.fn.startExperiment = function (group, experiment, force, result) {
  $(group).attr('disabled', 'disabled');
\r
+ var can_number = ($(this).attr("name") === "start_strain") ? 0 : 1;\r
  
  if (!experiment || !experiment.match(/^[a-zA-Z0-9_-]+$/)) {
    result.text("Experiment names must be composed of alphanumeric characters" + 
@@ -141,17 +146,42 @@ $.fn.startExperiment = function (group, experiment, force, result) {
  if (force) {
    data.force = 1;
  }
\r
+ //Start the experiment
  $.ajax({
    url : mctx.control.api,
    data : data
  }).done(function (data) {
    if (!result.checkStatus(data)) {
      return;
-   }
-   result.html("&nbsp;");
-   toggleControls(true);
- }).always(function () {
+   }\r
+   \r
+   //Select the can\r
+   $.ajax({\r
+    url : mctx.api + "actuators",\r
+    data : {name : "can_select", set : can_number}\r
+   }).done(function (data) {\r
+    if (!result.checkStatus(data)) {\r
+     return;\r
+    }\r
+    \r
+    //Enable the can\r
+    $.ajax({\r
+      url : mctx.api + 'actuators',\r
+      data : {name : "can_enable", set : 1}\r
+    }).done(function (data) {\r
+      if (!result.checkStatus(data)) {\r
+        return;\r
+      }\r
+      result.html("&nbsp;");\r
+      toggleControls(true);\r
+    }).always(function () {\r
+      $(group).removeAttr('disabled');\r
+    });\r
+   }).fail(function () {\r
+    $(group).removeAttr('disabled');\r
+   });
+ }).fail(function () {
    $(group).removeAttr('disabled');
  });
 };
@@ -187,11 +217,11 @@ $.fn.setPressure = function(pressure, result) {
     pressure[k] = n;
   }
   
-  var set = pressure['set'] + "," + pressure['wait'] + ","
-            pressure['size'] + "," + pressure['count'];
+  var set = pressure['set'] + "_" + pressure['wait'] + "_" +
+            pressure['step'] + "_" + pressure['count'];
   $.ajax({
     url : mctx.api + "actuators",
-    data : {id : mctx.actuator.pressure_regulator, set : set}
+    data : {name : "pregulator", set : set}
   }).done(function (data) {
     if (!result.checkStatus(data)) {
       return;
index de5ecb3..fd475ad 100644 (file)
@@ -67,13 +67,13 @@ $.fn.deployDevices = function(input_type, check_first, group) {
   var apply = function(dict, prefix) {
     $.each(dict, function(key, val) {
       var attributes = {
-          'type' : input_type, 'value' : key, 'alt' : val,
+          'type' : input_type, 'value' : key, 'alt' : val.name,
           'class' : prefix, 'name' : group, 
-          'id' : prefix + '_' + val //Unique id (name mangling)
+          'id' : prefix + '_' + val.name //Unique id (name mangling)
       };
       
       var entry = $("<input/>", attributes);
-      var label = $("<label/>", {'for' : prefix + '_' + val, 'text' : val}); 
+      var label = $("<label/>", {'for' : prefix + '_' + val.name, 'text' : val.name}); 
       entry.prop("checked", check_first);
       check_first = false;
       container.append(entry).append(label);
diff --git a/testing/MCTXWeb/public_html/stream.html b/testing/MCTXWeb/public_html/stream.html
new file mode 100644 (file)
index 0000000..69b08dc
--- /dev/null
@@ -0,0 +1,5 @@
+<head>
+<meta http-equiv="refresh" content="0">
+</head>
+
+<IMG SRC="/api/image">
index a27e003..c4863bd 100755 (executable)
@@ -13,7 +13,7 @@ import datetime
 import time
 
 #TODO: Replace with URL of testing server
-api_url = "https://daedalus/api"
+api_url = "https://192.168.1.10/api"
 
 def log(message):
        sys.stderr.write("%s: %s : %s\n" % (sys.argv[0], str(datetime.datetime.now()), message))

UCC git Repository :: git.ucc.asn.au