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
Diff: action.cpp
- 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(®); + break; + case MNE_MPP: + stack.pop(®); + 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 +}