IoT_watering project - supervisor

Dependencies:   mbed-rtos mbed ssWi

Committer:
mariob
Date:
Wed Jan 18 21:01:38 2017 +0000
Revision:
0:cc364516d433
Child:
1:dcfe7e79a45c
alpha release

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