mbed based IoT Gateway More details http://blog.thiseldo.co.uk/wp-filez/IoTGateway.pdf

Dependencies:   NetServices FatFileSystem csv_parser mbed MQTTClient RF12B DNSResolver SDFileSystem

Committer:
SomeRandomBloke
Date:
Wed May 09 20:29:30 2012 +0000
Revision:
5:0dbc27a7af55
Parent:
4:d460406ac780
Reduced debug output

Who changed what in which revision?

UserRevisionLine numberNew contents of line
SomeRandomBloke 0:a29a0225f203 1 /** IoT Gateway Routing for incoming messages
SomeRandomBloke 0:a29a0225f203 2 *
SomeRandomBloke 0:a29a0225f203 3 * @author Andrew Lindsay
SomeRandomBloke 0:a29a0225f203 4 *
SomeRandomBloke 0:a29a0225f203 5 * @section LICENSE
SomeRandomBloke 0:a29a0225f203 6 *
SomeRandomBloke 0:a29a0225f203 7 * Copyright (c) 2012 Andrew Lindsay (andrew [at] thiseldo [dot] co [dot] uk)
SomeRandomBloke 0:a29a0225f203 8 *
SomeRandomBloke 0:a29a0225f203 9 * Permission is hereby granted, free of charge, to any person obtaining a copy
SomeRandomBloke 0:a29a0225f203 10 * of this software and associated documentation files (the "Software"), to deal
SomeRandomBloke 0:a29a0225f203 11 * in the Software without restriction, including without limitation the rights
SomeRandomBloke 0:a29a0225f203 12 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
SomeRandomBloke 0:a29a0225f203 13 * copies of the Software, and to permit persons to whom the Software is
SomeRandomBloke 0:a29a0225f203 14 * furnished to do so, subject to the following conditions:
SomeRandomBloke 0:a29a0225f203 15
SomeRandomBloke 0:a29a0225f203 16 * The above copyright notice and this permission notice shall be included in
SomeRandomBloke 0:a29a0225f203 17 * all copies or substantial portions of the Software.
SomeRandomBloke 0:a29a0225f203 18 *
SomeRandomBloke 0:a29a0225f203 19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
SomeRandomBloke 0:a29a0225f203 20 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
SomeRandomBloke 0:a29a0225f203 21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
SomeRandomBloke 0:a29a0225f203 22 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
SomeRandomBloke 0:a29a0225f203 23 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
SomeRandomBloke 0:a29a0225f203 24 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
SomeRandomBloke 0:a29a0225f203 25 * THE SOFTWARE.
SomeRandomBloke 0:a29a0225f203 26 *
SomeRandomBloke 0:a29a0225f203 27 * @section DESCRIPTION
SomeRandomBloke 0:a29a0225f203 28 *
SomeRandomBloke 0:a29a0225f203 29 *
SomeRandomBloke 0:a29a0225f203 30 */
SomeRandomBloke 0:a29a0225f203 31
SomeRandomBloke 0:a29a0225f203 32 #include "mbed.h"
SomeRandomBloke 0:a29a0225f203 33 #include "RF12B.h"
SomeRandomBloke 0:a29a0225f203 34 #include "IoTRouting.h"
SomeRandomBloke 0:a29a0225f203 35 #include "csv_parser.h"
SomeRandomBloke 0:a29a0225f203 36 #include "PayloadV1.h"
SomeRandomBloke 0:a29a0225f203 37 #include "PayloadV2.h"
SomeRandomBloke 0:a29a0225f203 38 #include "PayloadSimple.h"
SomeRandomBloke 0:a29a0225f203 39 #include "OutputPachube.h"
SomeRandomBloke 0:a29a0225f203 40
SomeRandomBloke 0:a29a0225f203 41 //DigitalOut activityLED(p29, "activityLED");
SomeRandomBloke 0:a29a0225f203 42
SomeRandomBloke 0:a29a0225f203 43 #define iotRoutingFile "/iotfs/IOTRTG.TXT"
SomeRandomBloke 0:a29a0225f203 44 #define iotNodeDefFile "/iotfs/IOTNODE.TXT"
SomeRandomBloke 0:a29a0225f203 45
SomeRandomBloke 0:a29a0225f203 46
SomeRandomBloke 0:a29a0225f203 47 // Default Constructor
SomeRandomBloke 0:a29a0225f203 48 IoTRouting::IoTRouting() {}
SomeRandomBloke 0:a29a0225f203 49
SomeRandomBloke 0:a29a0225f203 50
SomeRandomBloke 0:a29a0225f203 51 void IoTRouting::addNodeToList(uint8_t groupId, uint8_t nodeId, uint8_t length, uint8_t type ) {
SomeRandomBloke 0:a29a0225f203 52 IoTNodeDef *pr = new IoTNodeDef();
SomeRandomBloke 0:a29a0225f203 53 pr->groupId = groupId;
SomeRandomBloke 0:a29a0225f203 54 pr->nodeId = nodeId;
SomeRandomBloke 0:a29a0225f203 55 pr->length = length;
SomeRandomBloke 0:a29a0225f203 56 pr->type = type;
SomeRandomBloke 0:a29a0225f203 57
SomeRandomBloke 0:a29a0225f203 58 _nodeDefList.push_back(pr);
SomeRandomBloke 0:a29a0225f203 59 }
SomeRandomBloke 0:a29a0225f203 60
SomeRandomBloke 0:a29a0225f203 61 void IoTRouting::addRoutingToList( short nodeId, short sensorId, float factor, byte outType,
SomeRandomBloke 0:a29a0225f203 62 char *param1, char *param2, char *param3, char *param4 ) {
SomeRandomBloke 0:a29a0225f203 63
SomeRandomBloke 0:a29a0225f203 64 PayloadRouting* pr = new PayloadRouting();
SomeRandomBloke 0:a29a0225f203 65 pr->nodeId = nodeId;
SomeRandomBloke 0:a29a0225f203 66 pr->sensorId = sensorId;
SomeRandomBloke 0:a29a0225f203 67
SomeRandomBloke 0:a29a0225f203 68 pr->factor = factor;
SomeRandomBloke 0:a29a0225f203 69 pr->outType = outType;
SomeRandomBloke 0:a29a0225f203 70
SomeRandomBloke 0:a29a0225f203 71 switch ( pr->outType ) {
SomeRandomBloke 0:a29a0225f203 72 case OUTPUT_TYPE_PACHUBE:
SomeRandomBloke 0:a29a0225f203 73 pr->output = pachubeOutput;
SomeRandomBloke 0:a29a0225f203 74 break;
SomeRandomBloke 0:a29a0225f203 75 case OUTPUT_TYPE_MQTT:
SomeRandomBloke 0:a29a0225f203 76 pr->output = mqttOutput;
SomeRandomBloke 0:a29a0225f203 77 break;
SomeRandomBloke 4:d460406ac780 78 case OUTPUT_TYPE_EMONCMS:
SomeRandomBloke 4:d460406ac780 79 pr->output = emonCmsOutput;
SomeRandomBloke 4:d460406ac780 80 break;
SomeRandomBloke 4:d460406ac780 81 case OUTPUT_TYPE_SENSE:
SomeRandomBloke 4:d460406ac780 82 pr->output = senSeOutput;
SomeRandomBloke 4:d460406ac780 83 break;
SomeRandomBloke 0:a29a0225f203 84 default:
SomeRandomBloke 0:a29a0225f203 85 pr->output = NULL;
SomeRandomBloke 0:a29a0225f203 86 break;
SomeRandomBloke 0:a29a0225f203 87 }
SomeRandomBloke 0:a29a0225f203 88
SomeRandomBloke 0:a29a0225f203 89 pr->param1 = new char[strlen(param1)+1];
SomeRandomBloke 0:a29a0225f203 90 strcpy(pr->param1, param1);
SomeRandomBloke 0:a29a0225f203 91 pr->param2 = new char[strlen(param2)+1];
SomeRandomBloke 0:a29a0225f203 92 strcpy(pr->param2, param2);
SomeRandomBloke 0:a29a0225f203 93 pr->param3 = new char[strlen(param3)+1];
SomeRandomBloke 0:a29a0225f203 94 strcpy(pr->param3, param3);
SomeRandomBloke 0:a29a0225f203 95 pr->param4 = new char[strlen(param4)+1];
SomeRandomBloke 0:a29a0225f203 96 strcpy(pr->param4, param4);
SomeRandomBloke 0:a29a0225f203 97 // printf("%d,%d,%f,%d,%s,%s,%s,%s\n",pr->nodeId, pr->sensorId, pr->factor, pr->outType, pr->param1, pr->param2, pr->param3, pr->param4);
SomeRandomBloke 0:a29a0225f203 98 _routing.push_back(pr);
SomeRandomBloke 0:a29a0225f203 99 }
SomeRandomBloke 0:a29a0225f203 100
SomeRandomBloke 0:a29a0225f203 101
SomeRandomBloke 0:a29a0225f203 102 void IoTRouting::initRouting() {
SomeRandomBloke 0:a29a0225f203 103 sendCount = 0;
SomeRandomBloke 0:a29a0225f203 104
SomeRandomBloke 0:a29a0225f203 105 FILE *fp = fopen(iotNodeDefFile, "r");
SomeRandomBloke 0:a29a0225f203 106 if (fp == NULL) {
SomeRandomBloke 0:a29a0225f203 107 printf("Could not open file %s for read\n", iotNodeDefFile);
SomeRandomBloke 0:a29a0225f203 108 return;
SomeRandomBloke 0:a29a0225f203 109 }
SomeRandomBloke 0:a29a0225f203 110
SomeRandomBloke 0:a29a0225f203 111 // read file
SomeRandomBloke 0:a29a0225f203 112
SomeRandomBloke 0:a29a0225f203 113 const char field_terminator = ',';
SomeRandomBloke 0:a29a0225f203 114 const char line_terminator = '\n';
SomeRandomBloke 0:a29a0225f203 115 const char enclosure_char = '"';
SomeRandomBloke 0:a29a0225f203 116
SomeRandomBloke 0:a29a0225f203 117 csv_parser file_parser;
SomeRandomBloke 0:a29a0225f203 118
SomeRandomBloke 0:a29a0225f203 119 /* Define how many records we're gonna skip. This could be used to skip the column definitions. */
SomeRandomBloke 0:a29a0225f203 120 file_parser.set_skip_lines(0);
SomeRandomBloke 0:a29a0225f203 121
SomeRandomBloke 0:a29a0225f203 122 /* Specify the file to parse */
SomeRandomBloke 0:a29a0225f203 123 file_parser.init(fp);
SomeRandomBloke 0:a29a0225f203 124
SomeRandomBloke 0:a29a0225f203 125 /* Here we tell the parser how to parse the file */
SomeRandomBloke 0:a29a0225f203 126 file_parser.set_enclosed_char(enclosure_char, ENCLOSURE_OPTIONAL);
SomeRandomBloke 0:a29a0225f203 127 file_parser.set_field_term_char(field_terminator);
SomeRandomBloke 0:a29a0225f203 128 file_parser.set_line_term_char(line_terminator);
SomeRandomBloke 0:a29a0225f203 129
SomeRandomBloke 0:a29a0225f203 130 /* Check to see if there are more records, then grab each row one at a time */
SomeRandomBloke 0:a29a0225f203 131
SomeRandomBloke 0:a29a0225f203 132 while (file_parser.has_more_rows()) {
SomeRandomBloke 0:a29a0225f203 133 csv_row row = file_parser.get_row();
SomeRandomBloke 0:a29a0225f203 134 if (row.size()<4) {
SomeRandomBloke 0:a29a0225f203 135 printf("row too short %d\n", row.size());
SomeRandomBloke 0:a29a0225f203 136 continue;
SomeRandomBloke 0:a29a0225f203 137 }
SomeRandomBloke 0:a29a0225f203 138 addNodeToList((uint8_t)atoi(row[0].c_str()), (uint8_t)atoi(row[1].c_str()),
SomeRandomBloke 0:a29a0225f203 139 (uint8_t)atoi(row[2].c_str()), (uint8_t)atoi(row[3].c_str()));
SomeRandomBloke 0:a29a0225f203 140 }
SomeRandomBloke 0:a29a0225f203 141
SomeRandomBloke 0:a29a0225f203 142 fclose(fp);
SomeRandomBloke 0:a29a0225f203 143
SomeRandomBloke 0:a29a0225f203 144 // printf("Finished loading routing data\n");
SomeRandomBloke 0:a29a0225f203 145
SomeRandomBloke 0:a29a0225f203 146 fp = fopen(iotRoutingFile, "r");
SomeRandomBloke 0:a29a0225f203 147 if (fp == NULL) {
SomeRandomBloke 0:a29a0225f203 148 printf("Could not open file %s for read\n", iotRoutingFile);
SomeRandomBloke 0:a29a0225f203 149 return;
SomeRandomBloke 0:a29a0225f203 150 }
SomeRandomBloke 0:a29a0225f203 151 // _routing=new list<PayloadRouting*>();
SomeRandomBloke 0:a29a0225f203 152
SomeRandomBloke 0:a29a0225f203 153 /* Define how many records we're gonna skip. This could be used to skip the column definitions. */
SomeRandomBloke 0:a29a0225f203 154 file_parser.set_skip_lines(0);
SomeRandomBloke 0:a29a0225f203 155
SomeRandomBloke 0:a29a0225f203 156 /* Specify the file to parse */
SomeRandomBloke 0:a29a0225f203 157 file_parser.init(fp);
SomeRandomBloke 0:a29a0225f203 158
SomeRandomBloke 0:a29a0225f203 159 /* Here we tell the parser how to parse the file */
SomeRandomBloke 0:a29a0225f203 160 file_parser.set_enclosed_char(enclosure_char, ENCLOSURE_OPTIONAL);
SomeRandomBloke 0:a29a0225f203 161 file_parser.set_field_term_char(field_terminator);
SomeRandomBloke 0:a29a0225f203 162 file_parser.set_line_term_char(line_terminator);
SomeRandomBloke 0:a29a0225f203 163
SomeRandomBloke 0:a29a0225f203 164 /* Check to see if there are more records, then grab each row one at a time */
SomeRandomBloke 0:a29a0225f203 165
SomeRandomBloke 0:a29a0225f203 166 while (file_parser.has_more_rows()) {
SomeRandomBloke 0:a29a0225f203 167 csv_row row = file_parser.get_row();
SomeRandomBloke 0:a29a0225f203 168 if (row.size()<6) {
SomeRandomBloke 0:a29a0225f203 169 printf("row too short %d\n", row.size());
SomeRandomBloke 0:a29a0225f203 170 continue;
SomeRandomBloke 0:a29a0225f203 171 }
SomeRandomBloke 0:a29a0225f203 172 addRoutingToList( atoi(row[0].c_str()), atoi(row[1].c_str()), atof(row[2].c_str()), atoi(row[3].c_str()),
SomeRandomBloke 0:a29a0225f203 173 (char*)row[4].c_str(), (char*)row[5].c_str(), (char*)row[6].c_str(), (char*)row[7].c_str() );
SomeRandomBloke 0:a29a0225f203 174 }
SomeRandomBloke 0:a29a0225f203 175
SomeRandomBloke 0:a29a0225f203 176 fclose(fp);
SomeRandomBloke 0:a29a0225f203 177
SomeRandomBloke 0:a29a0225f203 178 // printf("Finished loading routing data\n");
SomeRandomBloke 0:a29a0225f203 179
SomeRandomBloke 0:a29a0225f203 180 // if(!mqtt.connect("IoTGateway")){
SomeRandomBloke 0:a29a0225f203 181 // printf("\r\nConnect to server failed ..\r\n");
SomeRandomBloke 0:a29a0225f203 182 // return -1;
SomeRandomBloke 0:a29a0225f203 183 // }
SomeRandomBloke 0:a29a0225f203 184 }
SomeRandomBloke 0:a29a0225f203 185
SomeRandomBloke 0:a29a0225f203 186 // Write the current nodelist back to file
SomeRandomBloke 0:a29a0225f203 187 // First rename original file to iotsetup.bak
SomeRandomBloke 0:a29a0225f203 188 bool IoTRouting::writeNodeList() {
SomeRandomBloke 0:a29a0225f203 189
SomeRandomBloke 0:a29a0225f203 190 // Rename original file
SomeRandomBloke 0:a29a0225f203 191 // if( rename ( iotConfigFile.c_str(), iotConfigFileBak.c_str() ) != 0 ) {
SomeRandomBloke 0:a29a0225f203 192 // printf("Could not rename file %s\n", iotConfigFile);
SomeRandomBloke 0:a29a0225f203 193 // return false;
SomeRandomBloke 0:a29a0225f203 194 // }
SomeRandomBloke 0:a29a0225f203 195
SomeRandomBloke 0:a29a0225f203 196 FILE *fp = fopen(iotNodeDefFile, "w");
SomeRandomBloke 0:a29a0225f203 197 if (fp == NULL) {
SomeRandomBloke 0:a29a0225f203 198 printf("Could not open file %s for write\n", iotNodeDefFile);
SomeRandomBloke 0:a29a0225f203 199 return false;
SomeRandomBloke 0:a29a0225f203 200 }
SomeRandomBloke 0:a29a0225f203 201
SomeRandomBloke 0:a29a0225f203 202 for (short i=0; i<(int)_nodeDefList.size(); i++) {
SomeRandomBloke 0:a29a0225f203 203 IoTNodeDef *nd = (IoTNodeDef*)_nodeDefList.at(i);
SomeRandomBloke 0:a29a0225f203 204 // printf("%d,%d,%d,%d\n",nd->groupId,nd->nodeId, nd->length,nd->type );
SomeRandomBloke 0:a29a0225f203 205 fprintf(fp, "%d,%d,%d,%d\n",nd->groupId,nd->nodeId, nd->length,nd->type );
SomeRandomBloke 0:a29a0225f203 206 }
SomeRandomBloke 0:a29a0225f203 207
SomeRandomBloke 0:a29a0225f203 208 fclose(fp);
SomeRandomBloke 0:a29a0225f203 209
SomeRandomBloke 0:a29a0225f203 210 return true;
SomeRandomBloke 0:a29a0225f203 211 }
SomeRandomBloke 0:a29a0225f203 212
SomeRandomBloke 0:a29a0225f203 213 // Write the current nodelist back to file
SomeRandomBloke 0:a29a0225f203 214 // First rename original file to iotsetup.bak
SomeRandomBloke 0:a29a0225f203 215 bool IoTRouting::writeRoutingList() {
SomeRandomBloke 0:a29a0225f203 216
SomeRandomBloke 0:a29a0225f203 217 // Rename original file
SomeRandomBloke 0:a29a0225f203 218 // if( rename ( iotConfigFile.c_str(), iotConfigFileBak.c_str() ) != 0 ) {
SomeRandomBloke 0:a29a0225f203 219 // printf("Could not rename file %s\n", iotRoutingFile);
SomeRandomBloke 0:a29a0225f203 220 // return false;
SomeRandomBloke 0:a29a0225f203 221 // }
SomeRandomBloke 0:a29a0225f203 222
SomeRandomBloke 0:a29a0225f203 223 FILE *fp = fopen(iotRoutingFile, "w");
SomeRandomBloke 0:a29a0225f203 224 if (fp == NULL) {
SomeRandomBloke 0:a29a0225f203 225 printf("Could not open file %s for write\n", iotRoutingFile);
SomeRandomBloke 0:a29a0225f203 226 return false;
SomeRandomBloke 0:a29a0225f203 227 }
SomeRandomBloke 0:a29a0225f203 228
SomeRandomBloke 0:a29a0225f203 229 for ( short i=0; i<(short)_routing.size(); i++ ) {
SomeRandomBloke 0:a29a0225f203 230 PayloadRouting *pr = (PayloadRouting*)_routing.at(i);
SomeRandomBloke 0:a29a0225f203 231 // printf("%d,%d,%f,%d,%s,%s,%s,%s\n",pr->nodeId, pr->sensorId, pr->factor, pr->outType, pr->param1, pr->param2, pr->param3, pr->param4);
SomeRandomBloke 0:a29a0225f203 232 fprintf(fp, "%d,%d,%f,%d,%s,%s,%s,%s\n",pr->nodeId, pr->sensorId, pr->factor, pr->outType, pr->param1, pr->param2, pr->param3, pr->param4);
SomeRandomBloke 0:a29a0225f203 233 }
SomeRandomBloke 0:a29a0225f203 234
SomeRandomBloke 0:a29a0225f203 235 fclose(fp);
SomeRandomBloke 0:a29a0225f203 236
SomeRandomBloke 0:a29a0225f203 237 return true;
SomeRandomBloke 0:a29a0225f203 238 }
SomeRandomBloke 0:a29a0225f203 239
SomeRandomBloke 0:a29a0225f203 240 void IoTRouting::addOutput( OutputDef *output, short outType ) {
SomeRandomBloke 0:a29a0225f203 241 switch ( outType ) {
SomeRandomBloke 0:a29a0225f203 242 case OUTPUT_TYPE_PACHUBE:
SomeRandomBloke 0:a29a0225f203 243 pachubeOutput = output;
SomeRandomBloke 0:a29a0225f203 244 break;
SomeRandomBloke 0:a29a0225f203 245 case OUTPUT_TYPE_MQTT:
SomeRandomBloke 0:a29a0225f203 246 mqttOutput = output;
SomeRandomBloke 0:a29a0225f203 247 break;
SomeRandomBloke 4:d460406ac780 248 case OUTPUT_TYPE_EMONCMS:
SomeRandomBloke 4:d460406ac780 249 emonCmsOutput = output;
SomeRandomBloke 4:d460406ac780 250 break;
SomeRandomBloke 4:d460406ac780 251 case OUTPUT_TYPE_SENSE:
SomeRandomBloke 4:d460406ac780 252 senSeOutput = output;
SomeRandomBloke 4:d460406ac780 253 break;
SomeRandomBloke 0:a29a0225f203 254 default:
SomeRandomBloke 0:a29a0225f203 255 break;
SomeRandomBloke 0:a29a0225f203 256 }
SomeRandomBloke 0:a29a0225f203 257 }
SomeRandomBloke 0:a29a0225f203 258
SomeRandomBloke 0:a29a0225f203 259 PayloadRouting* IoTRouting::getRouting( short nodeId, short sensorId ) {
SomeRandomBloke 5:0dbc27a7af55 260 // printf("Getting routing info for node %d, sensor %d - ", nodeId, sensorId);
SomeRandomBloke 0:a29a0225f203 261 for ( short i=0; i<(short)_routing.size(); i++ ) {
SomeRandomBloke 0:a29a0225f203 262
SomeRandomBloke 0:a29a0225f203 263 PayloadRouting *pr = (PayloadRouting*)_routing.at(i);
SomeRandomBloke 0:a29a0225f203 264 // printf("Node %d, sensor %d\n", pr->nodeId, pr->sensorId);
SomeRandomBloke 0:a29a0225f203 265 if ( pr->nodeId == nodeId && pr->sensorId == sensorId ) {
SomeRandomBloke 5:0dbc27a7af55 266 // printf("Found!\n");
SomeRandomBloke 0:a29a0225f203 267 return pr;
SomeRandomBloke 0:a29a0225f203 268 }
SomeRandomBloke 0:a29a0225f203 269 }
SomeRandomBloke 5:0dbc27a7af55 270 // printf("NOT found\n");
SomeRandomBloke 0:a29a0225f203 271 // Add to routing list
SomeRandomBloke 0:a29a0225f203 272 addRoutingToList( nodeId, sensorId, 1.0, OUTPUT_UNKNOWN,"","","","");
SomeRandomBloke 0:a29a0225f203 273 // Save Routing list
SomeRandomBloke 0:a29a0225f203 274 writeRoutingList();
SomeRandomBloke 0:a29a0225f203 275
SomeRandomBloke 0:a29a0225f203 276 return NULL;
SomeRandomBloke 0:a29a0225f203 277 }
SomeRandomBloke 0:a29a0225f203 278
SomeRandomBloke 0:a29a0225f203 279
SomeRandomBloke 0:a29a0225f203 280 short IoTRouting::getPayloadType( uint8_t *data, short dataLen ) {
SomeRandomBloke 5:0dbc27a7af55 281 // printf("Getting payload type, size is %d - ",(int)_nodeDefList.size() );
SomeRandomBloke 0:a29a0225f203 282 for (short i=0; i<(int)_nodeDefList.size(); i++) {
SomeRandomBloke 0:a29a0225f203 283 // printf("%d, %ld, ",i, (int)_nodeDefList.at(i));
SomeRandomBloke 0:a29a0225f203 284 IoTNodeDef *nd = (IoTNodeDef*)_nodeDefList.at(i);
SomeRandomBloke 0:a29a0225f203 285 if ( nd->groupId == data[0] && nd->nodeId == (data[1] & 0x1f) && nd->length == data[2] ) {
SomeRandomBloke 5:0dbc27a7af55 286 // printf("Found %d\n", nd->type);
SomeRandomBloke 0:a29a0225f203 287 return nd->type;
SomeRandomBloke 0:a29a0225f203 288 }
SomeRandomBloke 0:a29a0225f203 289 }
SomeRandomBloke 5:0dbc27a7af55 290 // printf("NOT found\n");
SomeRandomBloke 0:a29a0225f203 291 // Add to node list
SomeRandomBloke 0:a29a0225f203 292 addNodeToList(data[0], data[1] & 0x1f, data[2], PAYLOAD_TYPE_UNKNOWN );
SomeRandomBloke 0:a29a0225f203 293 // Save NodeList
SomeRandomBloke 0:a29a0225f203 294 writeNodeList();
SomeRandomBloke 0:a29a0225f203 295 return PAYLOAD_TYPE_UNKNOWN;
SomeRandomBloke 0:a29a0225f203 296 }
SomeRandomBloke 0:a29a0225f203 297
SomeRandomBloke 5:0dbc27a7af55 298 #define TMPBUF_SIZE 20
SomeRandomBloke 0:a29a0225f203 299
SomeRandomBloke 0:a29a0225f203 300 bool IoTRouting::routePayload( uint8_t *data, short dataLen ) {
SomeRandomBloke 0:a29a0225f203 301 bool routed = false;
SomeRandomBloke 0:a29a0225f203 302 uint8_t *ptr = data;
SomeRandomBloke 0:a29a0225f203 303 PayloadSimple psimp;
SomeRandomBloke 0:a29a0225f203 304 PayloadV1 pv1;
SomeRandomBloke 0:a29a0225f203 305 PayloadV2 pv2;
SomeRandomBloke 0:a29a0225f203 306 PayloadRouting *pr = NULL;
SomeRandomBloke 5:0dbc27a7af55 307 char tmpBuf[TMPBUF_SIZE];
SomeRandomBloke 0:a29a0225f203 308
SomeRandomBloke 0:a29a0225f203 309 pachubeOutput->init(); // Just to be sure
SomeRandomBloke 0:a29a0225f203 310 printf("routePayload: ");
SomeRandomBloke 0:a29a0225f203 311 for ( int i = 0; i < dataLen; i++ )
SomeRandomBloke 0:a29a0225f203 312 printf("%02X ", *ptr++ );
SomeRandomBloke 0:a29a0225f203 313
SomeRandomBloke 0:a29a0225f203 314 printf("\n");
SomeRandomBloke 0:a29a0225f203 315
SomeRandomBloke 0:a29a0225f203 316 short payloadType = getPayloadType( data, dataLen );
SomeRandomBloke 0:a29a0225f203 317
SomeRandomBloke 0:a29a0225f203 318 printf("Group ID: %d Node ID: %d Length: %d Status: %02x, Payload type %d\n", data[0], data[1] & 0x1f, data[2], data[3], payloadType );
SomeRandomBloke 0:a29a0225f203 319
SomeRandomBloke 0:a29a0225f203 320 switch ( payloadType ) {
SomeRandomBloke 0:a29a0225f203 321 case PAYLOAD_TYPE_SIMPLE:
SomeRandomBloke 0:a29a0225f203 322 psimp = PayloadSimple( data, dataLen);
SomeRandomBloke 0:a29a0225f203 323 printf("SIMPLE NumReadings %d\n", psimp.numReadings());
SomeRandomBloke 0:a29a0225f203 324 for ( int n = 0; n<psimp.numReadings(); n++ ) {
SomeRandomBloke 0:a29a0225f203 325 printf("%d: %d - %d\n", n, psimp.sensorId(n), psimp.reading(n) );
SomeRandomBloke 0:a29a0225f203 326 // Get list of routing objects
SomeRandomBloke 0:a29a0225f203 327 pr = getRouting( psimp.nodeId(), psimp.sensorId(n) );
SomeRandomBloke 0:a29a0225f203 328 if ( pr != NULL ) {
SomeRandomBloke 0:a29a0225f203 329 if ( pr->output != NULL ) {
SomeRandomBloke 0:a29a0225f203 330 // printf("Pachube %d, %d, %f, %s, %s\n",pr->nodeId, pr->sensorId, pr->factor, pr->param1, pr->param2);
SomeRandomBloke 5:0dbc27a7af55 331 snprintf(tmpBuf, TMPBUF_SIZE, "%.3f", (float)(psimp.reading(n) * pr->factor));
SomeRandomBloke 5:0dbc27a7af55 332 // printf("Add to output %s, %s, %s\n", pr->param1, pr->param2, tmpBuf );
SomeRandomBloke 0:a29a0225f203 333 pr->output->addReading( pr->param1, pr->param2,tmpBuf );
SomeRandomBloke 0:a29a0225f203 334 }
SomeRandomBloke 0:a29a0225f203 335 }
SomeRandomBloke 0:a29a0225f203 336 }
SomeRandomBloke 0:a29a0225f203 337 if ( pr != NULL ) {
SomeRandomBloke 0:a29a0225f203 338 if ( pr->output != NULL )
SomeRandomBloke 0:a29a0225f203 339 pr->output->send();
SomeRandomBloke 0:a29a0225f203 340 }
SomeRandomBloke 0:a29a0225f203 341 routed = true;
SomeRandomBloke 0:a29a0225f203 342
SomeRandomBloke 0:a29a0225f203 343 break;
SomeRandomBloke 0:a29a0225f203 344 case PAYLOAD_TYPE_V1:
SomeRandomBloke 0:a29a0225f203 345 pv1 = PayloadV1( data, dataLen);
SomeRandomBloke 0:a29a0225f203 346 printf("V1 NumReadings %d, Node %d\n", pv1.numReadings(), pv1.nodeId() );
SomeRandomBloke 0:a29a0225f203 347
SomeRandomBloke 0:a29a0225f203 348 pr = getRouting( pv1.nodeId(), -1 );
SomeRandomBloke 0:a29a0225f203 349 if ( pr != NULL ) {
SomeRandomBloke 0:a29a0225f203 350 // Output to destination
SomeRandomBloke 0:a29a0225f203 351 // printf("Updating low battery feed\n");
SomeRandomBloke 0:a29a0225f203 352 if ( data[3] & STATUS_LOW_BATTERY ) {
SomeRandomBloke 0:a29a0225f203 353 printf("LOW Battery detected\n");
SomeRandomBloke 0:a29a0225f203 354 }
SomeRandomBloke 0:a29a0225f203 355 if ( pr->output != NULL ) {
SomeRandomBloke 5:0dbc27a7af55 356 snprintf(tmpBuf, TMPBUF_SIZE, "%d", (int)( data[3] & STATUS_LOW_BATTERY ));
SomeRandomBloke 0:a29a0225f203 357 pr->output->addReading( pr->param1, pr->param2, tmpBuf );
SomeRandomBloke 0:a29a0225f203 358 }
SomeRandomBloke 0:a29a0225f203 359 }
SomeRandomBloke 0:a29a0225f203 360 // Determine output
SomeRandomBloke 0:a29a0225f203 361 for ( int n = 0; n<pv1.numReadings(); n++ ) {
SomeRandomBloke 0:a29a0225f203 362 pr = getRouting(pv1.nodeId(), pv1.sensorId(n) );
SomeRandomBloke 0:a29a0225f203 363 if ( pr != NULL ) {
SomeRandomBloke 0:a29a0225f203 364 tmpBuf[0] = '\0';
SomeRandomBloke 0:a29a0225f203 365 // printf("Pachube %d, %d, %f, %s, %s\n",pr->nodeId, pr->sensorId, pr->factor, pr->param1, pr->param2);
SomeRandomBloke 0:a29a0225f203 366 if ( pr->output != NULL ) {
SomeRandomBloke 5:0dbc27a7af55 367 snprintf(tmpBuf, TMPBUF_SIZE, "%.3f", (float)(pv1.reading(n) * pr->factor));
SomeRandomBloke 0:a29a0225f203 368 pr->output->addReading( pr->param1, pr->param2, tmpBuf );
SomeRandomBloke 0:a29a0225f203 369 }
SomeRandomBloke 0:a29a0225f203 370 printf("%d: %d - %s\n", n, pv1.sensorId(n), tmpBuf );
SomeRandomBloke 0:a29a0225f203 371
SomeRandomBloke 0:a29a0225f203 372 }
SomeRandomBloke 0:a29a0225f203 373 }
SomeRandomBloke 0:a29a0225f203 374 if ( pr != NULL ) {
SomeRandomBloke 0:a29a0225f203 375 if ( pr->output != NULL )
SomeRandomBloke 0:a29a0225f203 376 pr->output->send();
SomeRandomBloke 0:a29a0225f203 377 }
SomeRandomBloke 0:a29a0225f203 378 routed = true;
SomeRandomBloke 0:a29a0225f203 379 break;
SomeRandomBloke 0:a29a0225f203 380 case PAYLOAD_TYPE_V2:
SomeRandomBloke 0:a29a0225f203 381 pv2 = PayloadV2( data, dataLen );
SomeRandomBloke 0:a29a0225f203 382 // printf("V2 NumReadings %d\n", pv2.numReadings());
SomeRandomBloke 0:a29a0225f203 383 pr = getRouting( pv2.nodeId(), -1 );
SomeRandomBloke 0:a29a0225f203 384 if ( pr != NULL ) {
SomeRandomBloke 0:a29a0225f203 385 // Output to destination
SomeRandomBloke 0:a29a0225f203 386 // printf("Updating low battery feed\n");
SomeRandomBloke 0:a29a0225f203 387 if ( data[3] & STATUS_LOW_BATTERY ) {
SomeRandomBloke 0:a29a0225f203 388 printf("LOW Battery detected\n");
SomeRandomBloke 0:a29a0225f203 389 }
SomeRandomBloke 0:a29a0225f203 390 if ( pr->output != NULL ) {
SomeRandomBloke 5:0dbc27a7af55 391 snprintf(tmpBuf, TMPBUF_SIZE, "%d", (int)( data[3] & STATUS_LOW_BATTERY ));
SomeRandomBloke 0:a29a0225f203 392 pr->output->addReading( pr->param1, pr->param2, tmpBuf );
SomeRandomBloke 0:a29a0225f203 393 }
SomeRandomBloke 0:a29a0225f203 394 // Need to update add reading to detect change in feed ID and send.
SomeRandomBloke 0:a29a0225f203 395 }
SomeRandomBloke 0:a29a0225f203 396
SomeRandomBloke 0:a29a0225f203 397 for ( int n = 0; n < pv2.numReadings(); n++ ) {
SomeRandomBloke 0:a29a0225f203 398 // printf("Getting reading %d node %d sensor id %d\n",n, pv2.nodeId(), pv2.sensorId(n) );
SomeRandomBloke 0:a29a0225f203 399 pr = getRouting( pv2.nodeId(), pv2.sensorId(n) );
SomeRandomBloke 0:a29a0225f203 400 if ( pr != NULL ) {
SomeRandomBloke 0:a29a0225f203 401 // printf("Item: pr %ld, out type %d\n", (int)pr, pr->outType);
SomeRandomBloke 0:a29a0225f203 402
SomeRandomBloke 0:a29a0225f203 403 // printf("readingType = %d\n",pv2.readingType( n ));
SomeRandomBloke 0:a29a0225f203 404 // printf("IoTRouting: output = %ld\n",(int)pr->output);
SomeRandomBloke 0:a29a0225f203 405
SomeRandomBloke 0:a29a0225f203 406 if ( pr->output != NULL ) {
SomeRandomBloke 0:a29a0225f203 407 tmpBuf[0] = '\0';
SomeRandomBloke 0:a29a0225f203 408
SomeRandomBloke 0:a29a0225f203 409 switch ( pv2.readingType( n ) ) {
SomeRandomBloke 0:a29a0225f203 410 case V2_DATATYPE_BYTE:
SomeRandomBloke 5:0dbc27a7af55 411 snprintf(tmpBuf, TMPBUF_SIZE, "%.3f", (float)(pv2.readingByte(n) * pr->factor));
SomeRandomBloke 0:a29a0225f203 412 break;
SomeRandomBloke 0:a29a0225f203 413 case V2_DATATYPE_SHORT:
SomeRandomBloke 5:0dbc27a7af55 414 snprintf(tmpBuf, TMPBUF_SIZE, "%.3f", (float)(pv2.readingShort(n) * pr->factor));
SomeRandomBloke 0:a29a0225f203 415 break;
SomeRandomBloke 0:a29a0225f203 416 case V2_DATATYPE_LONG:
SomeRandomBloke 5:0dbc27a7af55 417 snprintf(tmpBuf, TMPBUF_SIZE, "%.3f", (float)(pv2.readingLong(n) * pr->factor));
SomeRandomBloke 0:a29a0225f203 418 break;
SomeRandomBloke 0:a29a0225f203 419 case V2_DATATYPE_STRING:
SomeRandomBloke 0:a29a0225f203 420 break;
SomeRandomBloke 0:a29a0225f203 421 default:
SomeRandomBloke 0:a29a0225f203 422 break;
SomeRandomBloke 0:a29a0225f203 423 }
SomeRandomBloke 0:a29a0225f203 424 pr->output->addReading( pr->param1, pr->param2, tmpBuf );
SomeRandomBloke 0:a29a0225f203 425 }
SomeRandomBloke 0:a29a0225f203 426 }
SomeRandomBloke 0:a29a0225f203 427 }
SomeRandomBloke 0:a29a0225f203 428 if ( pr != NULL ) {
SomeRandomBloke 0:a29a0225f203 429 if ( pr->output != NULL )
SomeRandomBloke 0:a29a0225f203 430 pr->output->send();
SomeRandomBloke 0:a29a0225f203 431 }
SomeRandomBloke 0:a29a0225f203 432
SomeRandomBloke 0:a29a0225f203 433 routed = true;
SomeRandomBloke 0:a29a0225f203 434 break;
SomeRandomBloke 0:a29a0225f203 435 case PAYLOAD_TYPE_UNKNOWN: // Unknown node found
SomeRandomBloke 0:a29a0225f203 436 printf("Unknown payload type found\n");
SomeRandomBloke 0:a29a0225f203 437 break;
SomeRandomBloke 0:a29a0225f203 438 default:
SomeRandomBloke 0:a29a0225f203 439 printf("Unknown\n");
SomeRandomBloke 0:a29a0225f203 440 break;
SomeRandomBloke 0:a29a0225f203 441 }
SomeRandomBloke 0:a29a0225f203 442
SomeRandomBloke 0:a29a0225f203 443 pachubeOutput->send(); // Just in case anything left to send
SomeRandomBloke 0:a29a0225f203 444 printf("Finished routing\n");
SomeRandomBloke 0:a29a0225f203 445 return routed;
SomeRandomBloke 0:a29a0225f203 446 }
SomeRandomBloke 0:a29a0225f203 447