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
Routing/IoTRouting.cpp@4:d460406ac780, 2012-05-01 (annotated)
- Committer:
- SomeRandomBloke
- Date:
- Tue May 01 21:43:40 2012 +0000
- Revision:
- 4:d460406ac780
- Parent:
- 2:27714c8c9c0a
- Child:
- 5:0dbc27a7af55
Added output module for Sen.Se and emonCMS
Who changed what in which revision?
User | Revision | Line number | New 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 | 2:27714c8c9c0a | 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 | 0:a29a0225f203 | 266 | printf("Found!\n"); |
SomeRandomBloke | 0:a29a0225f203 | 267 | return pr; |
SomeRandomBloke | 0:a29a0225f203 | 268 | } |
SomeRandomBloke | 0:a29a0225f203 | 269 | } |
SomeRandomBloke | 0:a29a0225f203 | 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 | 0:a29a0225f203 | 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 | 0:a29a0225f203 | 286 | printf("Found %d\n", nd->type); |
SomeRandomBloke | 0:a29a0225f203 | 287 | return nd->type; |
SomeRandomBloke | 0:a29a0225f203 | 288 | } |
SomeRandomBloke | 0:a29a0225f203 | 289 | } |
SomeRandomBloke | 0:a29a0225f203 | 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 | 0:a29a0225f203 | 298 | |
SomeRandomBloke | 0:a29a0225f203 | 299 | bool IoTRouting::routePayload( uint8_t *data, short dataLen ) { |
SomeRandomBloke | 0:a29a0225f203 | 300 | bool routed = false; |
SomeRandomBloke | 0:a29a0225f203 | 301 | uint8_t *ptr = data; |
SomeRandomBloke | 0:a29a0225f203 | 302 | PayloadSimple psimp; |
SomeRandomBloke | 0:a29a0225f203 | 303 | PayloadV1 pv1; |
SomeRandomBloke | 0:a29a0225f203 | 304 | PayloadV2 pv2; |
SomeRandomBloke | 0:a29a0225f203 | 305 | PayloadRouting *pr = NULL; |
SomeRandomBloke | 0:a29a0225f203 | 306 | char tmpBuf[42]; |
SomeRandomBloke | 0:a29a0225f203 | 307 | |
SomeRandomBloke | 0:a29a0225f203 | 308 | pachubeOutput->init(); // Just to be sure |
SomeRandomBloke | 0:a29a0225f203 | 309 | printf("routePayload: "); |
SomeRandomBloke | 0:a29a0225f203 | 310 | for ( int i = 0; i < dataLen; i++ ) |
SomeRandomBloke | 0:a29a0225f203 | 311 | printf("%02X ", *ptr++ ); |
SomeRandomBloke | 0:a29a0225f203 | 312 | |
SomeRandomBloke | 0:a29a0225f203 | 313 | printf("\n"); |
SomeRandomBloke | 0:a29a0225f203 | 314 | |
SomeRandomBloke | 0:a29a0225f203 | 315 | short payloadType = getPayloadType( data, dataLen ); |
SomeRandomBloke | 0:a29a0225f203 | 316 | |
SomeRandomBloke | 0:a29a0225f203 | 317 | 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 | 318 | |
SomeRandomBloke | 0:a29a0225f203 | 319 | switch ( payloadType ) { |
SomeRandomBloke | 0:a29a0225f203 | 320 | case PAYLOAD_TYPE_SIMPLE: |
SomeRandomBloke | 0:a29a0225f203 | 321 | psimp = PayloadSimple( data, dataLen); |
SomeRandomBloke | 0:a29a0225f203 | 322 | printf("SIMPLE NumReadings %d\n", psimp.numReadings()); |
SomeRandomBloke | 0:a29a0225f203 | 323 | for ( int n = 0; n<psimp.numReadings(); n++ ) { |
SomeRandomBloke | 0:a29a0225f203 | 324 | printf("%d: %d - %d\n", n, psimp.sensorId(n), psimp.reading(n) ); |
SomeRandomBloke | 0:a29a0225f203 | 325 | // Get list of routing objects |
SomeRandomBloke | 0:a29a0225f203 | 326 | pr = getRouting( psimp.nodeId(), psimp.sensorId(n) ); |
SomeRandomBloke | 0:a29a0225f203 | 327 | if ( pr != NULL ) { |
SomeRandomBloke | 0:a29a0225f203 | 328 | if ( pr->output != NULL ) { |
SomeRandomBloke | 0:a29a0225f203 | 329 | // printf("Pachube %d, %d, %f, %s, %s\n",pr->nodeId, pr->sensorId, pr->factor, pr->param1, pr->param2); |
SomeRandomBloke | 0:a29a0225f203 | 330 | snprintf(tmpBuf, DATABUF_SIZE, "%.3f", (float)(psimp.reading(n) * pr->factor)); |
SomeRandomBloke | 0:a29a0225f203 | 331 | printf("Add to output %s, %s, %s\n", pr->param1, pr->param2, tmpBuf ); |
SomeRandomBloke | 0:a29a0225f203 | 332 | pr->output->addReading( pr->param1, pr->param2,tmpBuf ); |
SomeRandomBloke | 0:a29a0225f203 | 333 | } |
SomeRandomBloke | 0:a29a0225f203 | 334 | } |
SomeRandomBloke | 0:a29a0225f203 | 335 | } |
SomeRandomBloke | 0:a29a0225f203 | 336 | if ( pr != NULL ) { |
SomeRandomBloke | 0:a29a0225f203 | 337 | if ( pr->output != NULL ) |
SomeRandomBloke | 0:a29a0225f203 | 338 | pr->output->send(); |
SomeRandomBloke | 0:a29a0225f203 | 339 | } |
SomeRandomBloke | 0:a29a0225f203 | 340 | routed = true; |
SomeRandomBloke | 0:a29a0225f203 | 341 | |
SomeRandomBloke | 0:a29a0225f203 | 342 | break; |
SomeRandomBloke | 0:a29a0225f203 | 343 | case PAYLOAD_TYPE_V1: |
SomeRandomBloke | 0:a29a0225f203 | 344 | pv1 = PayloadV1( data, dataLen); |
SomeRandomBloke | 0:a29a0225f203 | 345 | printf("V1 NumReadings %d, Node %d\n", pv1.numReadings(), pv1.nodeId() ); |
SomeRandomBloke | 0:a29a0225f203 | 346 | |
SomeRandomBloke | 0:a29a0225f203 | 347 | pr = getRouting( pv1.nodeId(), -1 ); |
SomeRandomBloke | 0:a29a0225f203 | 348 | if ( pr != NULL ) { |
SomeRandomBloke | 0:a29a0225f203 | 349 | // Output to destination |
SomeRandomBloke | 0:a29a0225f203 | 350 | // printf("Updating low battery feed\n"); |
SomeRandomBloke | 0:a29a0225f203 | 351 | if ( data[3] & STATUS_LOW_BATTERY ) { |
SomeRandomBloke | 0:a29a0225f203 | 352 | printf("LOW Battery detected\n"); |
SomeRandomBloke | 0:a29a0225f203 | 353 | } |
SomeRandomBloke | 0:a29a0225f203 | 354 | if ( pr->output != NULL ) { |
SomeRandomBloke | 0:a29a0225f203 | 355 | snprintf(tmpBuf, DATABUF_SIZE, "%d", (int)( data[3] & STATUS_LOW_BATTERY )); |
SomeRandomBloke | 0:a29a0225f203 | 356 | pr->output->addReading( pr->param1, pr->param2, tmpBuf ); |
SomeRandomBloke | 0:a29a0225f203 | 357 | } |
SomeRandomBloke | 0:a29a0225f203 | 358 | } |
SomeRandomBloke | 0:a29a0225f203 | 359 | // Determine output |
SomeRandomBloke | 0:a29a0225f203 | 360 | for ( int n = 0; n<pv1.numReadings(); n++ ) { |
SomeRandomBloke | 0:a29a0225f203 | 361 | pr = getRouting(pv1.nodeId(), pv1.sensorId(n) ); |
SomeRandomBloke | 0:a29a0225f203 | 362 | if ( pr != NULL ) { |
SomeRandomBloke | 0:a29a0225f203 | 363 | tmpBuf[0] = '\0'; |
SomeRandomBloke | 0:a29a0225f203 | 364 | // printf("Pachube %d, %d, %f, %s, %s\n",pr->nodeId, pr->sensorId, pr->factor, pr->param1, pr->param2); |
SomeRandomBloke | 0:a29a0225f203 | 365 | if ( pr->output != NULL ) { |
SomeRandomBloke | 0:a29a0225f203 | 366 | snprintf(tmpBuf, DATABUF_SIZE, "%.3f", (float)(pv1.reading(n) * pr->factor)); |
SomeRandomBloke | 0:a29a0225f203 | 367 | pr->output->addReading( pr->param1, pr->param2, tmpBuf ); |
SomeRandomBloke | 0:a29a0225f203 | 368 | } |
SomeRandomBloke | 0:a29a0225f203 | 369 | printf("%d: %d - %s\n", n, pv1.sensorId(n), tmpBuf ); |
SomeRandomBloke | 0:a29a0225f203 | 370 | |
SomeRandomBloke | 0:a29a0225f203 | 371 | } |
SomeRandomBloke | 0:a29a0225f203 | 372 | } |
SomeRandomBloke | 0:a29a0225f203 | 373 | if ( pr != NULL ) { |
SomeRandomBloke | 0:a29a0225f203 | 374 | if ( pr->output != NULL ) |
SomeRandomBloke | 0:a29a0225f203 | 375 | pr->output->send(); |
SomeRandomBloke | 0:a29a0225f203 | 376 | } |
SomeRandomBloke | 0:a29a0225f203 | 377 | routed = true; |
SomeRandomBloke | 0:a29a0225f203 | 378 | break; |
SomeRandomBloke | 0:a29a0225f203 | 379 | case PAYLOAD_TYPE_V2: |
SomeRandomBloke | 0:a29a0225f203 | 380 | pv2 = PayloadV2( data, dataLen ); |
SomeRandomBloke | 0:a29a0225f203 | 381 | // printf("V2 NumReadings %d\n", pv2.numReadings()); |
SomeRandomBloke | 0:a29a0225f203 | 382 | pr = getRouting( pv2.nodeId(), -1 ); |
SomeRandomBloke | 0:a29a0225f203 | 383 | if ( pr != NULL ) { |
SomeRandomBloke | 0:a29a0225f203 | 384 | // Output to destination |
SomeRandomBloke | 0:a29a0225f203 | 385 | // printf("Updating low battery feed\n"); |
SomeRandomBloke | 0:a29a0225f203 | 386 | if ( data[3] & STATUS_LOW_BATTERY ) { |
SomeRandomBloke | 0:a29a0225f203 | 387 | printf("LOW Battery detected\n"); |
SomeRandomBloke | 0:a29a0225f203 | 388 | } |
SomeRandomBloke | 0:a29a0225f203 | 389 | if ( pr->output != NULL ) { |
SomeRandomBloke | 0:a29a0225f203 | 390 | snprintf(tmpBuf, DATABUF_SIZE, "%d", (int)( data[3] & STATUS_LOW_BATTERY )); |
SomeRandomBloke | 0:a29a0225f203 | 391 | pr->output->addReading( pr->param1, pr->param2, tmpBuf ); |
SomeRandomBloke | 0:a29a0225f203 | 392 | } |
SomeRandomBloke | 0:a29a0225f203 | 393 | // Need to update add reading to detect change in feed ID and send. |
SomeRandomBloke | 0:a29a0225f203 | 394 | } |
SomeRandomBloke | 0:a29a0225f203 | 395 | |
SomeRandomBloke | 0:a29a0225f203 | 396 | for ( int n = 0; n < pv2.numReadings(); n++ ) { |
SomeRandomBloke | 0:a29a0225f203 | 397 | // printf("Getting reading %d node %d sensor id %d\n",n, pv2.nodeId(), pv2.sensorId(n) ); |
SomeRandomBloke | 0:a29a0225f203 | 398 | pr = getRouting( pv2.nodeId(), pv2.sensorId(n) ); |
SomeRandomBloke | 0:a29a0225f203 | 399 | if ( pr != NULL ) { |
SomeRandomBloke | 0:a29a0225f203 | 400 | // printf("Item: pr %ld, out type %d\n", (int)pr, pr->outType); |
SomeRandomBloke | 0:a29a0225f203 | 401 | |
SomeRandomBloke | 0:a29a0225f203 | 402 | // printf("readingType = %d\n",pv2.readingType( n )); |
SomeRandomBloke | 0:a29a0225f203 | 403 | // printf("IoTRouting: output = %ld\n",(int)pr->output); |
SomeRandomBloke | 0:a29a0225f203 | 404 | |
SomeRandomBloke | 0:a29a0225f203 | 405 | if ( pr->output != NULL ) { |
SomeRandomBloke | 0:a29a0225f203 | 406 | tmpBuf[0] = '\0'; |
SomeRandomBloke | 0:a29a0225f203 | 407 | |
SomeRandomBloke | 0:a29a0225f203 | 408 | switch ( pv2.readingType( n ) ) { |
SomeRandomBloke | 0:a29a0225f203 | 409 | case V2_DATATYPE_BYTE: |
SomeRandomBloke | 0:a29a0225f203 | 410 | snprintf(tmpBuf, DATABUF_SIZE, "%.3f", (float)(pv2.readingByte(n) * pr->factor)); |
SomeRandomBloke | 0:a29a0225f203 | 411 | break; |
SomeRandomBloke | 0:a29a0225f203 | 412 | case V2_DATATYPE_SHORT: |
SomeRandomBloke | 0:a29a0225f203 | 413 | snprintf(tmpBuf, DATABUF_SIZE, "%.3f", (float)(pv2.readingShort(n) * pr->factor)); |
SomeRandomBloke | 0:a29a0225f203 | 414 | break; |
SomeRandomBloke | 0:a29a0225f203 | 415 | case V2_DATATYPE_LONG: |
SomeRandomBloke | 0:a29a0225f203 | 416 | snprintf(tmpBuf, DATABUF_SIZE, "%.3f", (float)(pv2.readingLong(n) * pr->factor)); |
SomeRandomBloke | 0:a29a0225f203 | 417 | break; |
SomeRandomBloke | 0:a29a0225f203 | 418 | case V2_DATATYPE_STRING: |
SomeRandomBloke | 0:a29a0225f203 | 419 | break; |
SomeRandomBloke | 0:a29a0225f203 | 420 | default: |
SomeRandomBloke | 0:a29a0225f203 | 421 | break; |
SomeRandomBloke | 0:a29a0225f203 | 422 | } |
SomeRandomBloke | 0:a29a0225f203 | 423 | pr->output->addReading( pr->param1, pr->param2, tmpBuf ); |
SomeRandomBloke | 0:a29a0225f203 | 424 | } |
SomeRandomBloke | 0:a29a0225f203 | 425 | } |
SomeRandomBloke | 0:a29a0225f203 | 426 | } |
SomeRandomBloke | 0:a29a0225f203 | 427 | if ( pr != NULL ) { |
SomeRandomBloke | 0:a29a0225f203 | 428 | if ( pr->output != NULL ) |
SomeRandomBloke | 0:a29a0225f203 | 429 | pr->output->send(); |
SomeRandomBloke | 0:a29a0225f203 | 430 | } |
SomeRandomBloke | 0:a29a0225f203 | 431 | |
SomeRandomBloke | 0:a29a0225f203 | 432 | routed = true; |
SomeRandomBloke | 0:a29a0225f203 | 433 | break; |
SomeRandomBloke | 0:a29a0225f203 | 434 | case PAYLOAD_TYPE_UNKNOWN: // Unknown node found |
SomeRandomBloke | 0:a29a0225f203 | 435 | printf("Unknown payload type found\n"); |
SomeRandomBloke | 0:a29a0225f203 | 436 | break; |
SomeRandomBloke | 0:a29a0225f203 | 437 | default: |
SomeRandomBloke | 0:a29a0225f203 | 438 | printf("Unknown\n"); |
SomeRandomBloke | 0:a29a0225f203 | 439 | break; |
SomeRandomBloke | 0:a29a0225f203 | 440 | } |
SomeRandomBloke | 0:a29a0225f203 | 441 | |
SomeRandomBloke | 0:a29a0225f203 | 442 | pachubeOutput->send(); // Just in case anything left to send |
SomeRandomBloke | 0:a29a0225f203 | 443 | printf("Finished routing\n"); |
SomeRandomBloke | 0:a29a0225f203 | 444 | return routed; |
SomeRandomBloke | 0:a29a0225f203 | 445 | } |
SomeRandomBloke | 0:a29a0225f203 | 446 |