IoT_watering project - supervisor

Dependencies:   mbed-rtos mbed ssWi

Committer:
mariob
Date:
Thu Jan 19 23:31:18 2017 +0000
Revision:
1:dcfe7e79a45c
Parent:
0:cc364516d433
Child:
2:69d2d4c76f02
fix

Who changed what in which revision?

UserRevisionLine numberNew contents of line
mariob 0:cc364516d433 1 #include "mbed.h"
mariob 0:cc364516d433 2 #include "rtos.h"
mariob 0:cc364516d433 3
mariob 1:dcfe7e79a45c 4 #include "config.h"
mariob 0:cc364516d433 5
mariob 0:cc364516d433 6 #include "xbee.hpp"
mariob 0:cc364516d433 7 #include "ssWiSocket.hpp"
mariob 0:cc364516d433 8
mariob 0:cc364516d433 9 int last_watering[MAX_NUM_NODES];
mariob 0:cc364516d433 10
mariob 1:dcfe7e79a45c 11 global_confg_t global_config;
mariob 1:dcfe7e79a45c 12
mariob 0:cc364516d433 13 ssWiSocket* socket_command;
mariob 0:cc364516d433 14 ssWiSocket* socket_moisture[MAX_NUM_NODES];
mariob 0:cc364516d433 15 ssWiSocket* socket_temperature[MAX_NUM_NODES];
mariob 0:cc364516d433 16 ssWiSocket* socket_humidity[MAX_NUM_NODES];
mariob 0:cc364516d433 17 ssWiSocket* socket_response[MAX_NUM_NODES];
mariob 0:cc364516d433 18 ssWiSocket* socket_water[MAX_NUM_NODES];
mariob 0:cc364516d433 19
mariob 0:cc364516d433 20 LocalFileSystem local("local");
mariob 0:cc364516d433 21
mariob 0:cc364516d433 22 bool read_counter();
mariob 0:cc364516d433 23 bool read_configuration();
mariob 0:cc364516d433 24
mariob 0:cc364516d433 25 bool read_from_port(ssWiSocket *socket, int *value);
mariob 0:cc364516d433 26
mariob 0:cc364516d433 27 bool read_timeout(ssWiSocket *socket, int *value);
mariob 0:cc364516d433 28
mariob 0:cc364516d433 29 void do_sampling();
mariob 0:cc364516d433 30 void do_watering();
mariob 0:cc364516d433 31
mariob 0:cc364516d433 32 int main() {
mariob 0:cc364516d433 33 // supervisor configuration
mariob 1:dcfe7e79a45c 34 printf("6\r\n");
mariob 0:cc364516d433 35 #ifdef DEBUG
mariob 0:cc364516d433 36 printf("SUPERVISOR - config\r\n");
mariob 0:cc364516d433 37 #endif
mariob 0:cc364516d433 38 if (!read_configuration())
mariob 0:cc364516d433 39 error("Impossible to read configuration");
mariob 0:cc364516d433 40
mariob 0:cc364516d433 41 // network configuration
mariob 0:cc364516d433 42 XBeeModule xbee(p9, p10, 102, 14);
mariob 0:cc364516d433 43 xbee.init(5, 10);
mariob 0:cc364516d433 44 socket_command = ssWiSocket::createSocket(PORT_COMMANDS);
mariob 0:cc364516d433 45 for (int i = 0; i < global_config.num_units; i++) {
mariob 0:cc364516d433 46 socket_moisture[i] = ssWiSocket::createSocket(
mariob 0:cc364516d433 47 global_config.nodes[i].address * 5 + PORT_MOISTURE_OFFSET);
mariob 0:cc364516d433 48 socket_temperature[i] = ssWiSocket::createSocket(
mariob 0:cc364516d433 49 global_config.nodes[i].address * 5 + PORT_TEMPERATURE_OFFSET);
mariob 0:cc364516d433 50 socket_humidity[i] = ssWiSocket::createSocket(
mariob 0:cc364516d433 51 global_config.nodes[i].address * 5 + PORT_HUMIDITY_OFFSET);
mariob 0:cc364516d433 52 socket_response[i] = ssWiSocket::createSocket(
mariob 0:cc364516d433 53 global_config.nodes[i].address * 5 + PORT_RESPONSE_OFFSET);
mariob 0:cc364516d433 54 socket_water[i] = ssWiSocket::createSocket(
mariob 0:cc364516d433 55 global_config.nodes[i].address * 5 + PORT_WATER_OFFSET);
mariob 0:cc364516d433 56 }
mariob 0:cc364516d433 57
mariob 0:cc364516d433 58 // initialize shared variables
mariob 0:cc364516d433 59 for (int i = 0; i < MAX_NUM_NODES; i++)
mariob 0:cc364516d433 60 last_watering[i] = 1;
mariob 0:cc364516d433 61
mariob 0:cc364516d433 62 // start
mariob 0:cc364516d433 63 #ifdef DEBUG
mariob 0:cc364516d433 64 printf("SUPERVISOR - start\r\n");
mariob 0:cc364516d433 65 #endif
mariob 1:dcfe7e79a45c 66
mariob 0:cc364516d433 67 while(1) {
mariob 0:cc364516d433 68 int minute_counters = 0;
mariob 0:cc364516d433 69 read_counter();
mariob 0:cc364516d433 70 #ifdef DEBUG
mariob 0:cc364516d433 71 printf("SUPERVISOR - wait...\r\n");
mariob 0:cc364516d433 72 #endif
mariob 0:cc364516d433 73 do {
mariob 0:cc364516d433 74 // wait 1 minute
mariob 0:cc364516d433 75 Thread::wait(INTERVAL_60_SECONDS * 1000);
mariob 0:cc364516d433 76 minute_counters++;
mariob 0:cc364516d433 77 } while (minute_counters < global_config.wait_minutes);
mariob 0:cc364516d433 78
mariob 1:dcfe7e79a45c 79 #ifdef DEBUG
mariob 1:dcfe7e79a45c 80 printf("SUPERVISOR - active\r\n");
mariob 1:dcfe7e79a45c 81 #endif
mariob 1:dcfe7e79a45c 82
mariob 0:cc364516d433 83 // mark as busy
mariob 0:cc364516d433 84 DigitalOut led_busy(LED4);
mariob 0:cc364516d433 85 led_busy = 1;
mariob 0:cc364516d433 86 FILE* fp_busy = fopen(FILE_BSY, "w");
mariob 0:cc364516d433 87
mariob 0:cc364516d433 88 // sample and water
mariob 0:cc364516d433 89 #ifdef DEBUG
mariob 0:cc364516d433 90 printf("SUPERVISOR - sampling\r\n");
mariob 0:cc364516d433 91 #endif
mariob 0:cc364516d433 92 do_sampling();
mariob 0:cc364516d433 93 #ifdef DEBUG
mariob 0:cc364516d433 94 printf("SUPERVISOR - watering\r\n");
mariob 0:cc364516d433 95 #endif
mariob 0:cc364516d433 96 do_watering();
mariob 1:dcfe7e79a45c 97
mariob 0:cc364516d433 98 // increment counter
mariob 0:cc364516d433 99 global_config.count++;
mariob 0:cc364516d433 100 FILE* fp = fopen(FILE_CNT, "w");
mariob 0:cc364516d433 101 fprintf(fp, "%d\n", global_config.count);
mariob 0:cc364516d433 102 fclose(fp);
mariob 0:cc364516d433 103
mariob 0:cc364516d433 104 // send shutdown
mariob 0:cc364516d433 105 #ifdef DEBUG
mariob 0:cc364516d433 106 printf("SUPERVISOR - shutdown\r\n");
mariob 0:cc364516d433 107 #endif
mariob 1:dcfe7e79a45c 108
mariob 1:dcfe7e79a45c 109 Timer t;
mariob 1:dcfe7e79a45c 110 t.start();
mariob 1:dcfe7e79a45c 111 while(t.read() < INTERVAL_SYNC);
mariob 0:cc364516d433 112 socket_command->write(COMM_SHUTDOWN);
mariob 1:dcfe7e79a45c 113
mariob 1:dcfe7e79a45c 114 t.stop(); t.reset(); t.start();
mariob 1:dcfe7e79a45c 115 while(t.read() < INTERVAL_SYNC);
mariob 1:dcfe7e79a45c 116
mariob 0:cc364516d433 117 // mark as not busy
mariob 0:cc364516d433 118 led_busy = 0;
mariob 0:cc364516d433 119 fclose(fp_busy);
mariob 0:cc364516d433 120 }
mariob 0:cc364516d433 121 }
mariob 0:cc364516d433 122
mariob 0:cc364516d433 123 void do_sampling () {
mariob 0:cc364516d433 124 FILE* fp = fopen(FILE_SNS, "a");
mariob 0:cc364516d433 125 Timer t;
mariob 0:cc364516d433 126
mariob 0:cc364516d433 127 socket_command->write(COMM_START_SAMPLING);
mariob 0:cc364516d433 128 t.start();
mariob 0:cc364516d433 129 while(t.read() < INTERVAL_SAMPLING);
mariob 0:cc364516d433 130
mariob 0:cc364516d433 131 socket_command->write(COMM_STOP_SAMPLING);
mariob 1:dcfe7e79a45c 132 t.stop();
mariob 1:dcfe7e79a45c 133 t.reset();
mariob 1:dcfe7e79a45c 134 t.start();
mariob 0:cc364516d433 135 while(t.read() < INTERVAL_SYNC);
mariob 0:cc364516d433 136
mariob 0:cc364516d433 137 for (int i = 0; i < global_config.num_units; i++) {
mariob 0:cc364516d433 138 int temp = 0, humi = 0, mois = 0, sampling_feedback = COMM_NO_VALUE;
mariob 0:cc364516d433 139 int code;
mariob 0:cc364516d433 140 if (!read_timeout(socket_response[i], &sampling_feedback))
mariob 0:cc364516d433 141 code = 1;
mariob 0:cc364516d433 142 else {
mariob 0:cc364516d433 143 switch (sampling_feedback) {
mariob 0:cc364516d433 144 case COMM_SAMPLING_OK:
mariob 0:cc364516d433 145 code = (read_timeout(socket_temperature[i], &temp) &&
mariob 0:cc364516d433 146 read_timeout(socket_humidity[i], &humi) &&
mariob 0:cc364516d433 147 read_timeout(socket_moisture[i], &mois)) ? 0 : 2;
mariob 0:cc364516d433 148 break;
mariob 0:cc364516d433 149 case COMM_SAMPLING_KO: code = 3; break;
mariob 0:cc364516d433 150 case COMM_SAMPLING_OUT: code = 4; break;
mariob 0:cc364516d433 151 default: code = 5;
mariob 0:cc364516d433 152 }
mariob 0:cc364516d433 153 }
mariob 0:cc364516d433 154 fprintf(fp, "%d %d %d %4.2f %4.2f %4.2f\n", global_config.count,
mariob 0:cc364516d433 155 global_config.nodes[i].address,
mariob 0:cc364516d433 156 code,
mariob 0:cc364516d433 157 (double)humi/10.0,
mariob 0:cc364516d433 158 (double)temp/10.0,
mariob 0:cc364516d433 159 (double)mois/10.0);
mariob 0:cc364516d433 160 }
mariob 0:cc364516d433 161 fclose(fp);
mariob 0:cc364516d433 162 }
mariob 0:cc364516d433 163
mariob 0:cc364516d433 164 void do_watering () {
mariob 0:cc364516d433 165 for (int i = 0; i < global_config.num_units; i++) {
mariob 0:cc364516d433 166 if (global_config.count % global_config.nodes[i].watering_wait)
mariob 0:cc364516d433 167 continue;
mariob 0:cc364516d433 168 FILE* fp = fopen(FILE_WTR, "a");
mariob 0:cc364516d433 169
mariob 0:cc364516d433 170 socket_water[i]->write(global_config.nodes[i].watering_seconds);
mariob 0:cc364516d433 171
mariob 0:cc364516d433 172 Timer t;
mariob 0:cc364516d433 173 t.start();
mariob 1:dcfe7e79a45c 174 while (t.read() < (global_config.nodes[i].watering_seconds +
mariob 1:dcfe7e79a45c 175 INTERVAL_SYNC));
mariob 1:dcfe7e79a45c 176
mariob 1:dcfe7e79a45c 177 t.stop(); t.reset(); t.start();
mariob 1:dcfe7e79a45c 178 while (t.read() < INTERVAL_1_SECOND);
mariob 0:cc364516d433 179
mariob 0:cc364516d433 180 socket_command->write(COMM_START_WATERING_OFFSET +
mariob 0:cc364516d433 181 global_config.nodes[i].address);
mariob 1:dcfe7e79a45c 182
mariob 1:dcfe7e79a45c 183 t.stop(); t.reset(); t.start();
mariob 0:cc364516d433 184 while (t.read() < (global_config.nodes[i].watering_seconds +
mariob 0:cc364516d433 185 INTERVAL_SYNC));
mariob 0:cc364516d433 186 t.stop();
mariob 0:cc364516d433 187
mariob 0:cc364516d433 188 int watering_response = 0;
mariob 0:cc364516d433 189 int code = 4;
mariob 0:cc364516d433 190 if (read_timeout(socket_response[i], &watering_response)) {
mariob 0:cc364516d433 191 switch(watering_response) {
mariob 0:cc364516d433 192 case COMM_WATERING_KO: code = 1; break;
mariob 0:cc364516d433 193 case COMM_WATERING_OK: code = 0; break;
mariob 0:cc364516d433 194 case COMM_LOW_WATER_LEVEL: code = 2; break;
mariob 0:cc364516d433 195 default: code = 3;
mariob 0:cc364516d433 196 }
mariob 0:cc364516d433 197 }
mariob 0:cc364516d433 198 fprintf(fp, "%d %d %d %d\n", global_config.count,
mariob 0:cc364516d433 199 global_config.nodes[i].address,
mariob 0:cc364516d433 200 code,
mariob 0:cc364516d433 201 global_config.nodes[i].watering_seconds);
mariob 0:cc364516d433 202 fclose(fp);
mariob 0:cc364516d433 203 }
mariob 0:cc364516d433 204 }
mariob 0:cc364516d433 205
mariob 0:cc364516d433 206 bool read_from_port(ssWiSocket *socket, int *value) {
mariob 0:cc364516d433 207 int prev = *value;
mariob 0:cc364516d433 208 *value = socket->read();
mariob 0:cc364516d433 209 return (*value) != prev;
mariob 0:cc364516d433 210 }
mariob 0:cc364516d433 211
mariob 0:cc364516d433 212 bool read_timeout(ssWiSocket *socket, int *value) {
mariob 0:cc364516d433 213 Timer t;
mariob 0:cc364516d433 214 t.start();
mariob 0:cc364516d433 215 bool ret;
mariob 0:cc364516d433 216 int v = COMM_NO_VALUE;
mariob 0:cc364516d433 217 double start = t.read();
mariob 0:cc364516d433 218 do {
mariob 0:cc364516d433 219 if ((t.read() - start) > TIMEOUT_READ)
mariob 0:cc364516d433 220 return false;
mariob 0:cc364516d433 221 ret = read_from_port(socket, &v);
mariob 0:cc364516d433 222 } while(!ret);
mariob 0:cc364516d433 223 t.stop();
mariob 0:cc364516d433 224 *value = v;
mariob 0:cc364516d433 225 return true;
mariob 0:cc364516d433 226 }
mariob 0:cc364516d433 227
mariob 0:cc364516d433 228 bool read_configuration() {
mariob 0:cc364516d433 229 int state = 0;
mariob 0:cc364516d433 230 int n_unit = 0;
mariob 0:cc364516d433 231
mariob 0:cc364516d433 232 // read configuration file
mariob 0:cc364516d433 233 FILE *fp = fopen(FILE_CFG, "r");
mariob 0:cc364516d433 234 if(fp == NULL)
mariob 0:cc364516d433 235 return false;
mariob 0:cc364516d433 236 char line[250];
mariob 0:cc364516d433 237
mariob 0:cc364516d433 238 while(fgets(line, sizeof(line), fp)) {
mariob 0:cc364516d433 239 if (line[0] == '#')
mariob 0:cc364516d433 240 continue;
mariob 0:cc364516d433 241 switch(state) {
mariob 0:cc364516d433 242 case 0: //read interval length
mariob 0:cc364516d433 243 sscanf(line, "%d\r", &global_config.wait_minutes);
mariob 0:cc364516d433 244 state = 1;
mariob 0:cc364516d433 245 break;
mariob 0:cc364516d433 246 case 1: //read number of watering units
mariob 0:cc364516d433 247 sscanf(line, "%d\r", &global_config.num_units);
mariob 0:cc364516d433 248 state = 2;
mariob 0:cc364516d433 249 break;
mariob 0:cc364516d433 250 case 2: //read number of watering units
mariob 0:cc364516d433 251 sscanf(line, "%d %d %d\r",
mariob 0:cc364516d433 252 &global_config.nodes[n_unit].address,
mariob 0:cc364516d433 253 &global_config.nodes[n_unit].watering_wait,
mariob 0:cc364516d433 254 &global_config.nodes[n_unit].watering_seconds);
mariob 0:cc364516d433 255 n_unit++;
mariob 0:cc364516d433 256 if (n_unit >= global_config.num_units || n_unit >=MAX_NUM_NODES)
mariob 0:cc364516d433 257 state = 3;
mariob 0:cc364516d433 258 break;
mariob 0:cc364516d433 259 }
mariob 0:cc364516d433 260 }
mariob 0:cc364516d433 261 fclose(fp);
mariob 0:cc364516d433 262
mariob 0:cc364516d433 263 return true;
mariob 0:cc364516d433 264 }
mariob 0:cc364516d433 265
mariob 0:cc364516d433 266 bool read_counter () {
mariob 0:cc364516d433 267 // read counter
mariob 0:cc364516d433 268 FILE *fp = fopen(FILE_CNT, "r");
mariob 0:cc364516d433 269 if(fp == NULL) {
mariob 0:cc364516d433 270 fp = fopen(FILE_CNT, "w");
mariob 0:cc364516d433 271 if(fp == NULL)
mariob 0:cc364516d433 272 return false;
mariob 0:cc364516d433 273 global_config.count = 0;
mariob 0:cc364516d433 274 fprintf(fp, "0\n");
mariob 0:cc364516d433 275 } else
mariob 0:cc364516d433 276 fscanf(fp, "%d\n", &global_config.count);
mariob 0:cc364516d433 277 fclose(fp);
mariob 0:cc364516d433 278
mariob 0:cc364516d433 279 return true;
mariob 0:cc364516d433 280 }