IoT_watering project - supervisor

Dependencies:   mbed-rtos mbed ssWi

Committer:
mariob
Date:
Mon Jan 23 20:36:42 2017 +0000
Revision:
2:69d2d4c76f02
Parent:
1:dcfe7e79a45c
Child:
3:e49dd7bf7f1c
review

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