Andrew Boyson / Mbed 2 deprecated heating

Dependencies:   1-wire clock crypto fram log lpc1768 net web wiz mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers program.c Source File

program.c

00001 #include <stdint.h>
00002 #include <stdlib.h>
00003 #include <stdbool.h>
00004 
00005 #include "rtc.h"
00006 #include "clktime.h"
00007 #include "clk.h"
00008 #include "log.h"
00009 #include "settings.h"
00010 #include "program.h"
00011 #include "http.h"
00012 
00013 static char    programDay[7];
00014 static int16_t programs[PROGRAM_COUNT][PROGRAM_TRANSITIONS_COUNT];
00015 static char    programNewDayHour;
00016 
00017 void ProgramSetDay       (int i, int  value) { programDay[i] = (char)value; SetProgramDay(i, programDay + i); }
00018 int  ProgramGetDay       (int i)             { return (int) programDay[i];    }
00019 
00020 void ProgramSetNewDayHour(       int  value) { programNewDayHour    = (char)value; SetProgramNewDayHour(&programNewDayHour); }
00021 int  ProgramGetNewDayHour()                  { return (int) programNewDayHour;}
00022 
00023 int ProgramInit()
00024 {
00025     for (int i = 0; i <             7; i++) GetProgramDay(i, programDay + i);
00026     for (int i = 0; i < PROGRAM_COUNT; i++) GetProgram   (i, programs[i]);
00027     GetProgramNewDayHour(&programNewDayHour);
00028     return 0;
00029 }
00030 
00031 /*
00032 There are three programs available [0|1|2]; any of which can be allocated to a given day [0-6].
00033 Each program contains four transitions with an index [0|1|2|3].
00034 A transition is defined to be a short (16 bit) and consists of:
00035 +---------+--------+--------+---------+
00036 | 15 - 13 |   12   |   11   | 10 - 00 |
00037 +---------+--------+--------+---------+
00038 |         | in use | switch | minute  |
00039 |         | yes/no | on/off | in day  |
00040 |         |   1/0  |  1/0   | 0-1439  |
00041 +---------+--------+--------+---------+
00042 */
00043 static int16_t encodeTransition(bool inuse, bool onoff, int minutes)
00044 {
00045     int16_t    transition  = minutes;
00046                transition &= 0x07FF;
00047     if (onoff) transition |= 0x0800;
00048     if (inuse) transition |= 0x1000;
00049     return transition;
00050 }
00051 static void decodeTransition(int16_t transition, bool* pinuse, bool* ponoff, int* pminutes)
00052 {
00053     *pinuse   = transition & 0x1000;
00054     *ponoff   = transition & 0x0800;
00055     *pminutes = transition & 0x07FF;
00056 }
00057 
00058 static int compareTransition (const void * a, const void * b) //-ve a goes before b; 0 same; +ve a goes after b
00059 {
00060     bool  inUseA,   inUseB;
00061     bool     onA,      onB;
00062     int minutesA, minutesB;
00063     decodeTransition(*(int16_t*)a, &inUseA, &onA, &minutesA);
00064     decodeTransition(*(int16_t*)b, &inUseB, &onB, &minutesB);
00065     
00066     if (!inUseA && !inUseB) return  0;
00067     if (!inUseA)            return +1;
00068     if (!inUseB)            return -1;
00069     
00070     if (minutesA < programNewDayHour * 60) minutesA += 1440;
00071     if (minutesB < programNewDayHour * 60) minutesB += 1440;
00072     
00073     if (minutesA < minutesB) return -1;
00074     if (minutesA > minutesB) return +1;
00075     return 0;
00076 }
00077 static void sort(int16_t* pProgram)
00078 {
00079     qsort (pProgram, 4, sizeof(int16_t), compareTransition);
00080 }
00081 
00082 //[+|-][00-23][00-59];
00083 void ProgramToString(int program, int buflen, char* buffer)
00084 {
00085     if (buflen < 25) return;
00086     char* p = buffer;
00087     for (int i = 0; i < PROGRAM_TRANSITIONS_COUNT; i++)
00088     {
00089         int16_t transition = programs[program][i];
00090         bool  inuse;
00091         bool  on;
00092         int   minuteUnits;
00093         decodeTransition(transition, &inuse, &on, &minuteUnits);
00094         if (!inuse) continue;
00095         
00096         int minuteTens  = minuteUnits / 10; minuteUnits %= 10;
00097         int   hourUnits = minuteTens  /  6; minuteTens  %=  6;
00098         int   hourTens  =   hourUnits / 10;   hourUnits %= 10;
00099         
00100         if (p > buffer) *p++ = ' ';
00101         *p++ = on ? '+' : '-';
00102         *p++ = hourTens    + '0';
00103         *p++ = hourUnits   + '0';
00104         *p++ = minuteTens  + '0';
00105         *p++ = minuteUnits + '0';
00106     }
00107     *p = 0;
00108 }
00109 void ProgramSendAjax()
00110 {
00111     for (int program = 0; program < PROGRAM_COUNT; program++)
00112     {
00113         for (int transition = 0; transition < PROGRAM_TRANSITIONS_COUNT; transition++)
00114         {
00115             bool  inuse;
00116             bool  on;
00117             int   minuteUnits;
00118             decodeTransition(programs[program][transition], &inuse, &on, &minuteUnits);
00119             if (!inuse) continue;
00120             
00121             int minuteTens  = minuteUnits / 10; minuteUnits %= 10;
00122             int   hourUnits = minuteTens  /  6; minuteTens  %=  6;
00123             int   hourTens  =   hourUnits / 10;   hourUnits %= 10;
00124             
00125             if (transition) HttpAddChar(' ');
00126             HttpAddChar(on ? '+' : '-');
00127             HttpAddChar(hourTens    + '0');
00128             HttpAddChar(hourUnits   + '0');
00129             HttpAddChar(minuteTens  + '0');
00130             HttpAddChar(minuteUnits + '0');
00131         }
00132         HttpAddChar('\n');
00133     }
00134 }
00135 static void handleParseDelim(int program, int* pIndex, bool* pInUse, bool* pOn, int* pHourTens,  int* pHourUnits, int* pMinuteTens, int* pMinuteUnits)
00136 {
00137     int hour = *pHourTens * 10 + *pHourUnits;
00138     if (hour   <  0) *pInUse = false;
00139     if (hour   > 23) *pInUse = false;
00140     
00141     int minute = *pMinuteTens * 10 + *pMinuteUnits;
00142     if (minute <  0) *pInUse = false;
00143     if (minute > 59) *pInUse = false;
00144     
00145     int minutes = hour * 60 + minute;
00146     
00147     int16_t transition = encodeTransition(*pInUse, *pOn, minutes);
00148     programs[program][*pIndex] = transition;
00149     
00150     *pIndex      += 1;
00151     *pInUse       = 0;
00152     *pOn          = 0;
00153     *pHourTens    = 0;
00154     *pHourUnits   = 0;
00155     *pMinuteTens  = 0;
00156     *pMinuteUnits = 0;
00157 
00158 }
00159 void ProgramParse(int program, char* p)
00160 {
00161     int            i = 0;
00162     bool       inUse = 0;  bool         on = 0;
00163     int    hourUnits = 0;  int    hourTens = 0;
00164     int  minuteUnits = 0;  int  minuteTens = 0;
00165     while (*p && i < PROGRAM_TRANSITIONS_COUNT) 
00166     {
00167         if      (*p == '+')              { on = true ; }
00168         else if (*p == '-')              { on = false; }
00169         else if (*p >= '0' && *p <= '9') { inUse = true; hourTens = hourUnits; hourUnits = minuteTens; minuteTens = minuteUnits; minuteUnits = *p - '0'; }
00170         else if (*p == ' ')              { handleParseDelim(program, &i, &inUse, &on, &hourTens, &hourUnits, &minuteTens, &minuteUnits); }
00171         p++;
00172     }
00173     while (i < PROGRAM_TRANSITIONS_COUNT) handleParseDelim(program, &i, &inUse, &on, &hourTens, &hourUnits, &minuteTens, &minuteUnits);
00174     sort(programs[program]);
00175     SetProgram(program, programs[program]);
00176 }
00177 
00178 static bool readProgramTimerOutput()
00179 {   
00180 
00181     if (!ClkTimeIsSet()) return 0;
00182 
00183     struct tm tm;
00184     ClkNowTmLocal(&tm);
00185     
00186     int dayOfWeek = tm.tm_wday;
00187     int minutesNow = tm.tm_hour * 60 + tm.tm_min;
00188     if (tm.tm_hour < programNewDayHour) //Before 2am should be matched against yesterday's program.
00189     {
00190         dayOfWeek--;
00191         if (dayOfWeek < 0) dayOfWeek = 6;
00192     }
00193     
00194     int program = programDay[dayOfWeek];
00195     
00196     bool calling = 0;
00197     for (int i = 0; i < PROGRAM_TRANSITIONS_COUNT; i++)
00198     {
00199         int16_t transition = programs[program][i];
00200         bool inuse;
00201         bool on;
00202         int  minutes;
00203         decodeTransition(transition, &inuse, &on, &minutes);
00204         if (!inuse) continue;
00205         if (minutes <= minutesNow) calling = on;
00206     }
00207     
00208     return calling;
00209 }
00210 
00211 bool ProgramTimerOutput;
00212 
00213 int ProgramMain()
00214 {    
00215     ProgramTimerOutput = readProgramTimerOutput();
00216     return 0;
00217 }