mbed Weather Platform firmware http://mbed.org/users/okini3939/notebook/mbed-weather-platform-firmware/

Dependencies:   EthernetNetIf SDHCFileSystem I2CLEDDisp Agentbed NTPClient_NetServices mbed BMP085 HTTPClient ConfigFile I2CLCD

Revision:
18:9286e5010c14
Child:
19:69b77f9e0446
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/action.cpp	Tue May 31 15:40:14 2011 +0000
@@ -0,0 +1,417 @@
+/** @file
+ * @brief mbed Weather Platform
+ */
+#include "mbed.h"
+#include "weather.h"
+#include "Stack.h"
+
+
+struct MNE_str {
+    eMNEMONIC mne;
+    char str[5];
+};
+
+#define CF_MNE_NUM 25
+const struct MNE_str mne_str[CF_MNE_NUM] = {
+    {MNE_LD, "LD"}, {MNE_LDI, "LDI"}, {MNE_LDP, "LDP"}, {MNE_LDF, "LDF"},
+    {MNE_ALD, "@LD"}, {MNE_ALDI, "@LDI"}, {MNE_ALDP, "@LDP"}, {MNE_ALDF, "@LDF"},
+    {MNE_OR, "OR"}, {MNE_ORI, "ORI"}, {MNE_ORP, "ORP"}, {MNE_ORF, "ORF"},
+    {MNE_AND, "AND"}, {MNE_ANI, "ANI"}, {MNE_ANDP, "ANDP"}, {MNE_ANDF, "ANDF"},
+    {MNE_ORB, "ORB"}, {MNE_ANB, "ANB"}, {MNE_INV, "INV"},
+    {MNE_MPS, "MPS"}, {MNE_MRD, "MRD"}, {MNE_MPP, "MPP"},
+    {MNE_OUT, "OUT"}, {MNE_SET, "SET"}, {MNE_RST, "RST"},
+};
+
+struct EXP_str {
+    eEXPRESSION exp;
+    char str[3];
+};
+
+#define CF_EXP_NUM 10
+const struct EXP_str exp_str[CF_EXP_NUM] = {
+    {EXP_EQ, "=="}, {EXP_EQ, "="}, {EXP_NE, "!="}, {EXP_NE, "<>"},
+    {EXP_LT, "<="}, {EXP_LE, "<"}, {EXP_GT, ">"}, {EXP_GE, ">="},
+    {EXP_MOD, "%"}, {EXP_NMOD, "!%"},
+};
+
+
+int check_exp (Sensor *s, int i) {
+    int keynum;
+    float value, check;
+    struct tm *tim;
+
+    tim = localtime(&s->sec);
+    keynum = conf.actions[i].keynum;
+    check = conf.actions[i].value;
+
+    // left value
+    value = 0;
+    switch (conf.actions[i].key) {
+    case 'P':
+        value = s->pres;
+        break;
+    case 'T':
+        value = s->temp;
+        break;
+    case 'H':
+        value = s->humi;
+        break;
+    case 'A':
+        value = s->anemo;
+        break;
+    case 'V':
+        value = s->vane;
+        break;
+    case 'R':
+        value = s->rain;
+        break;
+    case 'L':
+        value = s->light;
+        break;
+    case 'U':
+        value = s->uv;
+        break;
+    case 'M':
+        value = s->moist;
+        break;
+
+    case 'y':
+        value = tim->tm_year + 1900;
+        break;
+    case 'm':
+        value = tim->tm_mon;
+        break;
+    case 'd':
+        value = tim->tm_mday;
+        break;
+    case 'h':
+        value = tim->tm_hour;
+        break;
+    case 'i':
+        value = tim->tm_min;
+        break;
+    case 's':
+        value = tim->tm_sec;
+        break;
+
+    case '0':
+        value = 0;
+        break;
+    case '1':
+        value = 1;
+        break;
+
+    case 'I': // INPUT
+        if (keynum >= INPUT_NUM) break;
+        value = s->input[keynum];
+        break;
+    case 'Q': // OUTPUT
+        if (keynum >= OUTPUT_NUM) break;
+        value = s->output[keynum];
+        break;
+    case 't': // Timer
+        if (keynum >= TIMER_NUM) break;
+        if (conf.actions[i].expression == EXP_NULL) {
+            value = s->timer_flg[keynum] && s->timer_cnt[keynum] == 0;
+        } else {
+            value = s->timer_cnt[keynum];
+        }
+        break;
+    case 'c': // Counter
+        if (keynum >= COUNTER_NUM) break;
+        value = s->count[keynum];
+        break;
+    }
+
+    // expression, right value
+    switch (conf.actions[i].expression) {
+    case EXP_EQ:
+        return value == check;
+    case EXP_NE:
+        return value != check;
+    case EXP_LE:
+        return value <= check;
+    case EXP_LT:
+        return value < check;
+    case EXP_GE:
+        return value >= check;
+    case EXP_GT:
+        return value > check;
+    case EXP_MOD:
+        return (int)value % (int)check;
+    case EXP_NMOD:
+        return ! (int)value % (int)check;
+    }
+
+    return value != 0;
+}
+
+void exec_action (int i, int reg, eMNEMONIC sr) {
+    static int tw_old = 0;
+    int keynum;
+
+    keynum = conf.actions[i].keynum;
+
+    switch (conf.actions[i].key) {
+    case 'P': // Pachube
+        if (conf.ipaddr[0] && conf.pachube_apikey[0] && conf.pachube_feedid[0] && reg) {
+            pachube(csv);
+        }
+        break;
+
+    case 'S': // Weather Stations
+        if (conf.ipaddr[0] && conf.stations_id[0] && conf.stations_pin[0] && reg) {
+            weatherstations();
+        }
+        break;
+
+    case 'T': // Twitter
+        if (conf.ipaddr[0] && conf.twitter_user[0] && conf.twitter_pwd[0]) {
+            if (sr == MNE_OUT && reg) {
+                twitter(keynum);
+            } else
+            if (sr == MNE_SET && reg && tw_old == 0) {
+                twitter(keynum);
+                tw_old = 1;
+            } else
+            if (reg == 0) {
+                tw_old = 0;
+            }
+        }
+        break;
+
+    case 'X': // XBee
+        if (reg) {
+            xbee.printf(csv);
+        }
+        break;
+
+    case 'Q': // OUTPUT
+        if (keynum >= OUTPUT_NUM) break;
+        if (sr == MNE_OUT) {
+            sensor.output[keynum] = reg;
+        } else
+        if (sr == MNE_SET && reg) {
+            sensor.output[keynum] = 1;
+        } else
+        if (sr == MNE_RST && reg) {
+            sensor.output[keynum] = 0;
+        }
+        break;
+
+    case 't': // Timer
+        if (keynum >= TIMER_NUM) break;
+        if (sr == MNE_OUT) {
+            // set timer
+            if (sensor.timer_flg[keynum]) sensor.timer_cnt[keynum] = conf.actions[i].value * 10;
+            sensor.timer_flg[keynum] = reg;
+        } else
+        if (sr == MNE_SET && reg) {
+            sensor.timer_cnt[keynum] = conf.actions[i].value * 10;
+        } else
+        if (sr == MNE_RST && reg) {
+            sensor.timer_flg[keynum] = 0;
+        }
+        break;
+
+    case 'c': // Counter
+        if (keynum >= COUNTER_NUM) break;
+        if (sr == MNE_OUT && reg) {
+            sensor.count[keynum] ++;
+        } else
+        if (sr == MNE_RST && reg) {
+            sensor.count[keynum] = 0;
+        }
+
+    }
+
+#ifdef DEBUG
+    pc.printf("[%c%d] reg=%d sr=%d\r\n", conf.actions[i].key, keynum, reg, sr);
+#endif
+}
+
+int action (char enable) {
+    int i;
+    char j, reg, ena;
+    Stack stack(40);
+
+    sensor.sec = time(NULL) + (60 * 60 * 9);
+    sensor.input[0] = conf.inputtype ? *aimoist > 0.5 : 0;
+    sensor.input[1] = swin2;
+
+    for(i = 0; i < conf.actionscount; i ++) {
+        switch (conf.actions[i].mnemonic) {
+        case MNE_LD:
+            stack.push(reg);
+            reg = check_exp(&sensor, i);
+            ena = enable;
+            break;
+        case MNE_LDI:
+            stack.push(reg);
+            reg = ! check_exp(&sensor, i);
+            ena = enable;
+            break;
+        case MNE_LDP:
+            stack.push(reg);
+            reg = check_exp(&sensor, i) && ! check_exp(&sensor_old, i);
+            ena = enable;
+            break;
+        case MNE_LDF:
+            stack.push(reg);
+            reg = ! check_exp(&sensor, i) && check_exp(&sensor_old, i);
+            ena = enable;
+            break;
+
+        case MNE_ALD:
+            stack.push(reg);
+            reg = check_exp(&sensor, i);
+            ena = 1;
+            break;
+        case MNE_ALDI:
+            stack.push(reg);
+            reg = ! check_exp(&sensor, i);
+            ena = 1;
+            break;
+        case MNE_ALDP:
+            stack.push(reg);
+            reg = check_exp(&sensor, i) && ! check_exp(&sensor_old, i);
+            ena = 1;
+            break;
+        case MNE_ALDF:
+            stack.push(reg);
+            reg = ! check_exp(&sensor, i) && check_exp(&sensor_old, i);
+            ena = 1;
+            break;
+
+        case MNE_AND:
+            reg = reg && check_exp(&sensor, i);
+            break;
+        case MNE_ANI:
+            reg = reg && ! check_exp(&sensor, i);
+            break;
+        case MNE_ANDP:
+            reg = reg && (check_exp(&sensor, i) && ! check_exp(&sensor_old, i));
+            break;
+        case MNE_ANDF:
+            reg = reg && (! check_exp(&sensor, i) && check_exp(&sensor_old, i));
+            break;
+
+        case MNE_OR:
+            reg = reg || check_exp(&sensor, i);
+            break;
+        case MNE_ORI:
+            reg = reg || ! check_exp(&sensor, i);
+            break;
+        case MNE_ORP:
+            reg = reg || (check_exp(&sensor, i) && ! check_exp(&sensor_old, i));
+            break;
+        case MNE_ORF:
+            reg = reg || (! check_exp(&sensor, i) && check_exp(&sensor_old, i));
+            break;
+
+        case MNE_ANB:
+            if (stack.pop(&j)) return -1;
+            reg = reg && j;
+            break;
+        case MNE_ORB:
+            if (stack.pop(&j)) return -1;
+            reg = reg || j;
+            break;
+
+        case MNE_INV:
+            reg = ! reg;
+            break;
+
+        case MNE_MPS:
+            stack.push(reg);
+            break;
+        case MNE_MRD:
+            stack.read(&reg);
+            break;
+        case MNE_MPP:
+            stack.pop(&reg);
+            break;
+
+        case MNE_OUT:
+        case MNE_SET:
+        case MNE_RST:
+            if (ena) exec_action(i, reg, conf.actions[i].mnemonic);
+            break;
+        }
+    }
+
+    led3 = swout1 = sensor.output[0];
+    led4 = swout2 = sensor.output[1];
+#ifdef DEBUG
+    printf("timer %d\r\n", sensor.timer_cnt[0]);
+#endif
+
+    sensor_old = sensor;
+    return 0;
+}
+
+void load_exp (int i, char *buf) {
+    int j, len;
+    char *tmp;
+
+    conf.actions[i].key = buf[0];
+    conf.actions[i].keynum = strtol(&buf[1], &tmp, 10);
+    conf.actions[i].expression = EXP_NULL;
+    conf.actions[i].value = 0;
+
+    if (tmp) {
+        for (j = 0; j < CF_EXP_NUM; j ++) {
+            len = strlen(exp_str[j].str);
+            if (strncmp(tmp, exp_str[j].str, len) == 0 && tmp[len] >= '0' && tmp[len] <= '9') {
+                conf.actions[i].expression = exp_str[j].exp;
+                conf.actions[i].value = atof(&tmp[len]);
+                break;
+            }
+        }
+    }
+}
+
+void load_action (char *file) {
+    FILE *fp;
+    char c;
+    int i, j, count, len;
+    char buf[20];
+
+    fp = fopen(file, "r");
+    if (fp == NULL) return;
+
+    i = 0;
+    for (count = 0; count < CF_ACTION_NUM;) {
+        c = fgetc(fp);
+        if (feof(fp)) break;
+
+        if (c != '\r' && c != '\n' && i < 40 - 1) {
+            buf[i] = c;
+            i ++;
+            continue;
+        }
+        buf[i] = 0;
+
+        for (j = 0; j < CF_MNE_NUM; j ++) {
+            len = strlen(mne_str[j].str);
+            if (strncmp(buf, mne_str[j].str, len) == 0 && buf[len] == ' ') {
+                conf.actions[count].mnemonic = mne_str[j].mne;
+                load_exp(count, &buf[len + 1]);
+                count ++;
+                break;
+            }
+            if (strncmp(buf, "END", 3) == 0) break;
+        }
+
+        i = 0;
+    }
+
+    fclose(fp);    
+    conf.actionscount = count;
+
+#ifdef DEBUG
+    for (i = 0; i < count; i ++) {
+        pc.printf("M=%d [%c%d] E=%d V=%f\r\n", conf.actions[i].mnemonic, conf.actions[i].key, conf.actions[i].keynum, conf.actions[i].expression, conf.actions[i].value);
+    }
+#endif
+}