@@ -13,7 +13,7 @@ version 2 as published by the Free Software Foundation.
13
13
#include " utility/MsTimer2.h"
14
14
15
15
char V_0[] PROGMEM = " TEMP" ; // V_TEMP
16
- char V_1[] PROGMEM = " HUM" ; // V_HUM
16
+ char V_1[] PROGMEM = " HUM" ; // V_HUM
17
17
char V_2[] PROGMEM = " LIGHT" ; // V_LIGHT
18
18
char V_3[] PROGMEM = " DIMMER" ; // V_DIMMER
19
19
char V_4[] PROGMEM = " PRESSURE" ; // V_PRESSURE
@@ -23,7 +23,7 @@ char V_7[] PROGMEM = "RAINRATE"; //V_RAINRATE
23
23
char V_8[] PROGMEM = " WIND" ; // V_WIND
24
24
char V_9[] PROGMEM = " GUST" ; // V_GUST
25
25
char V_10[] PROGMEM = " DIRECTON" ; // V_DIRECTON
26
- char V_11[] PROGMEM = " UV" ; // V_UV
26
+ char V_11[] PROGMEM = " UV" ; // V_UV
27
27
char V_12[] PROGMEM = " WEIGHT" ; // V_WEIGHT
28
28
char V_13[] PROGMEM = " DISTANCE" ; // V_DISTANCE
29
29
char V_14[] PROGMEM = " IMPEDANCE" ; // V_IMPEDANCE
@@ -35,20 +35,20 @@ char V_19[] PROGMEM = "SCENE_ON"; //V_SCENE_ON
35
35
char V_20[] PROGMEM = " SCENE_OFF" ; // V_SCENE_OFF
36
36
char V_21[] PROGMEM = " HEATER" ; // V_HEATER
37
37
char V_22[] PROGMEM = " HEATER_SW" ; // V_HEATER_SW
38
- char V_23[] PROGMEM = " LIGHT_LEVEL" ; // V_LIGHT_LEVEL
38
+ char V_23[] PROGMEM = " LIGHT_LEVEL" ;// V_LIGHT_LEVEL
39
39
char V_24[] PROGMEM = " VAR1" ; // V_VAR1
40
40
char V_25[] PROGMEM = " VAR2" ; // V_VAR2
41
41
char V_26[] PROGMEM = " VAR3" ; // V_VAR3
42
42
char V_27[] PROGMEM = " VAR4" ; // V_VAR4
43
43
char V_28[] PROGMEM = " VAR5" ; // V_VAR5
44
- char V_29[] PROGMEM = " UP" ; // V_UP
44
+ char V_29[] PROGMEM = " UP" ; // V_UP
45
45
char V_30[] PROGMEM = " DOWN" ; // V_DOWN
46
46
char V_31[] PROGMEM = " STOP" ; // V_STOP
47
47
char V_32[] PROGMEM = " IR_SEND" ; // V_IR_SEND
48
48
char V_33[] PROGMEM = " IR_RECEIVE" ; // V_IR_RECEIVE
49
49
char V_34[] PROGMEM = " FLOW" ; // V_FLOW
50
50
char V_35[] PROGMEM = " VOLUME" ; // V_VOLUME
51
- char V_36[] PROGMEM = " LOCK_STATUS" ; // V_LOCK_STATUS
51
+ char V_36[] PROGMEM = " LOCK_STATUS" ;// V_LOCK_STATUS
52
52
char V_37[] PROGMEM = " DUST_LEVEL" ; // V_DUST_LEVEL
53
53
char V_38[] PROGMEM = " VOLTAGE" ; // V_VOLTAGE
54
54
char V_39[] PROGMEM = " CURRENT" ; // V_CURRENT
@@ -72,10 +72,10 @@ char V_56[] PROGMEM = ""; //
72
72
char V_57[] PROGMEM = " " ; //
73
73
char V_58[] PROGMEM = " " ; //
74
74
char V_59[] PROGMEM = " " ; //
75
- char V_60[] PROGMEM = " Started!\n " ; // Custom for MQTTGateway
75
+ char V_60[] PROGMEM = " Started!\n " ; // Custom for MQTTGateway
76
76
char V_61[] PROGMEM = " SKETCH_NAME" ; // Custom for MQTTGateway
77
77
char V_62[] PROGMEM = " SKETCH_VERSION" ; // Custom for MQTTGateway
78
- char V_63[] PROGMEM = " UNKNOWN" ; // Custom for MQTTGateway
78
+ char V_63[] PROGMEM = " UNKNOWN" ; // Custom for MQTTGateway
79
79
80
80
// ////////////////////////////////////////////////////////////////
81
81
@@ -89,7 +89,6 @@ PROGMEM const char *vType[] = {
89
89
V_61, V_62, V_63
90
90
};
91
91
92
-
93
92
char broker[] PROGMEM = MQTT_BROKER_PREFIX;
94
93
95
94
#define S_FIRSTCUSTOM 60
@@ -132,7 +131,7 @@ void MyMQTT::begin(rf24_pa_dbm_e paLevel, uint8_t channel, rf24_datarate_e dataR
132
131
Serial.begin (BAUD_RATE);
133
132
repeaterMode = true ;
134
133
isGateway = true ;
135
- MQTTClientConnected = false ;
134
+ MQTTClients = 0 ;
136
135
137
136
setupRepeaterMode ();
138
137
dataCallback = inDataCallback;
@@ -163,77 +162,120 @@ void MyMQTT::processRadioMessage() {
163
162
if (process ()) {
164
163
// A new message was received from one of the sensors
165
164
MyMessage message = getLastMessage ();
166
- // Pass along the message from sensors to serial line
167
165
rxBlink (1 );
168
- SendMQTT (message);
169
- }
170
166
167
+ if (msg.isAck ()) {
168
+ Serial.println (" msg is ack!" );
169
+ if (msg.sender == 255 && mGetCommand (msg) == C_INTERNAL && msg.type == I_ID_REQUEST) {
170
+ // TODO: sending ACK request on id_response fucks node up. doesn't work.
171
+ // The idea was to confirm id and save to EEPROM_LATEST_NODE_ADDRESS.
172
+ }
173
+ } else {
174
+ // we have to check every message if its a newly assigned id or not.
175
+ // Ack on I_ID_RESPONSE does not work, and checking on C_PRESENTATION isn't reliable.
176
+ uint8_t newNodeID = loadState (EEPROM_LATEST_NODE_ADDRESS)+1 ;
177
+ if (newNodeID <= MQTT_FIRST_SENSORID) {
178
+ newNodeID = MQTT_FIRST_SENSORID;
179
+ }
180
+ if (msg.sender == newNodeID) {
181
+ saveState (EEPROM_LATEST_NODE_ADDRESS,newNodeID);
182
+ }
183
+
184
+ if (mGetCommand (msg) == C_INTERNAL) {
185
+ if (msg.type == I_CONFIG) {
186
+ txBlink (1 );
187
+ if (!sendRoute (build (msg, GATEWAY_ADDRESS, msg.sender , 255 , C_INTERNAL, I_CONFIG, 0 ).set (" M" ))) {
188
+ errBlink (1 );
189
+ }
190
+ } else if (msg.type == I_ID_REQUEST && msg.sender == 255 ) {
191
+ uint8_t newNodeID = loadState (EEPROM_LATEST_NODE_ADDRESS)+1 ;
192
+ if (newNodeID <= MQTT_FIRST_SENSORID) {
193
+ newNodeID = MQTT_FIRST_SENSORID;
194
+ }
195
+ if (newNodeID >= MQTT_LAST_SENSORID) {
196
+ // Sorry no more id's left :(
197
+ newNodeID = AUTO;
198
+ }
199
+ txBlink (1 );
200
+ if (!sendRoute (build (msg, GATEWAY_ADDRESS, msg.sender , 255 , C_INTERNAL, I_ID_RESPONSE, 0 ).set (newNodeID))) {
201
+ errBlink (1 );
202
+ }
203
+ }
204
+ } else if (mGetCommand (msg)!= C_PRESENTATION) {
205
+ // Pass along the message from sensors to MQTT
206
+ SendMQTT (message);
207
+ }
208
+ }
209
+ }
171
210
}
172
211
173
212
void MyMQTT::processMQTTMessage (char *inputString, uint8_t inputPos) {
174
- char *str, *p;
213
+ char *str, *p, *payload= NULL ;
175
214
uint8_t i = 0 ;
176
215
buffer[0 ]= 0 ;
177
216
buffsize = 0 ;
217
+ uint8_t mqttMsgType = (uint8_t )inputString[0 ] >> 4 ;
178
218
179
- if (( uint8_t )inputString[ 0 ] >> 4 == MQTTCONNECT) {
219
+ if (mqttMsgType == MQTTCONNECT) {
180
220
buffer[buffsize++] = MQTTCONNACK << 4 ;
181
221
buffer[buffsize++] = 0x02 ; // Remaining length
182
222
buffer[buffsize++] = 0x00 ; // Connection accepted
183
223
buffer[buffsize++] = 0x00 ; // Reserved
184
- MQTTClientConnected=true ; // We have connection!
185
- }
186
- if ((uint8_t )inputString[0 ] >> 4 == MQTTPINGREQ) {
224
+ MQTTClients++; // We have a new client connected!
225
+ } else if (mqttMsgType == MQTTPINGREQ) {
187
226
buffer[buffsize++] = MQTTPINGRESP << 4 ;
188
227
buffer[buffsize++] = 0x00 ;
189
- }
190
- if ((uint8_t )inputString[0 ] >> 4 == MQTTSUBSCRIBE) {
191
- buffer[buffsize++] = MQTTSUBACK << 4 ; // Just ack everything, we actually dont really care!
192
- buffer[buffsize++] = 0x03 ; // Remaining length
228
+ } else if (mqttMsgType == MQTTSUBSCRIBE) {
229
+ buffer[buffsize++] = MQTTSUBACK << 4 ; // Just ack everything, we actually dont really care!
230
+ buffer[buffsize++] = 0x03 ; // Remaining length
193
231
buffer[buffsize++] = (uint8_t )inputString[2 ]; // Message ID MSB
194
232
buffer[buffsize++] = (uint8_t )inputString[3 ]; // Message ID LSB
195
- buffer[buffsize++] = MQTTQOS0; // QOS level
196
- }
197
- if ((uint8_t )inputString[0 ] >> 4 == MQTTUNSUBSCRIBE) {
233
+ buffer[buffsize++] = MQTTQOS0; // QOS level
234
+ } else if (mqttMsgType == MQTTUNSUBSCRIBE) {
198
235
buffer[buffsize++] = MQTTUNSUBACK << 4 ;
199
- buffer[buffsize++] = 0x02 ; // Remaining length
236
+ buffer[buffsize++] = 0x02 ; // Remaining length
200
237
buffer[buffsize++] = (uint8_t )inputString[2 ]; // Message ID MSB
201
238
buffer[buffsize++] = (uint8_t )inputString[3 ]; // Message ID LSB
239
+ } else if (mqttMsgType == MQTTDISCONNECT) {
240
+ MQTTClients--; // Client disconnected!
202
241
}
203
- if ((uint8_t )inputString[0 ] >> 4 == MQTTDISCONNECT) {
204
- MQTTClientConnected=false ; // We lost connection!
205
- }
242
+
206
243
if (buffsize > 0 ) {
207
- dataCallback (buffer,&buffsize);
244
+ dataCallback (buffer, &buffsize);
208
245
}
209
246
210
247
// We publish everything we get, we dont care if its subscribed or not!
211
- if (( uint8_t )inputString[ 0 ] >> 4 == MQTTPUBLISH || (MQTT_SEND_SUBSCRIPTION && ( uint8_t )inputString[ 0 ] >> 4 == MQTTSUBSCRIBE)) {
212
- buffer[0 ]= 0 ;
248
+ if (mqttMsgType == MQTTPUBLISH || (MQTT_SEND_SUBSCRIPTION && mqttMsgType == MQTTSUBSCRIBE)) {
249
+ buffer[0 ] = 0 ;
213
250
buffsize = 0 ;
214
251
// Cut out address and payload depending on message type.
215
- if (( uint8_t )inputString[ 0 ] >> 4 == MQTTSUBSCRIBE) {
216
- strncat (buffer,inputString+6 ,inputString[5 ]);
252
+ if (mqttMsgType == MQTTSUBSCRIBE) {
253
+ strncat (buffer, inputString+6 , inputString[5 ]);
217
254
} else {
218
- strncat (buffer,inputString+4 ,inputString[3 ]);
255
+ strncat (buffer, inputString+4 , inputString[3 ]);
219
256
}
220
257
221
258
// TODO: Check if we should send ack or not.
222
- for (str = strtok_r (buffer," /" ,&p) ; str && i<4 ; str = strtok_r (NULL ," /" ,&p)) {
259
+ for (str = strtok_r (buffer, " /" , &p) ; str && i<4 ; str = strtok_r (NULL , " /" , &p)) {
223
260
if (i == 0 ) {
224
- if (strcmp_P (str,broker)!=0 ) { // look for MQTT_BROKER_PREFIX
225
- return ; // Message not for us or malformatted!
261
+ // look for MQTT_BROKER_PREFIX
262
+ if (strcmp_P (str, broker) != 0 ) {
263
+ // Message not for us or malformatted!
264
+ return ;
226
265
}
227
266
} else if (i==1 ) {
228
- msg.destination = atoi (str); // NodeID
267
+ // NodeID
268
+ msg.destination = atoi (str);
229
269
} else if (i==2 ) {
230
- msg.sensor = atoi (str); // SensorID
270
+ // SensorID
271
+ msg.sensor = atoi (str);
231
272
} else if (i==3 ) {
232
- char match= 0 ; // SensorType
233
- // strcpy(str,( char*)&str[2]); //Strip V_
273
+ // SensorType
274
+ char match= 0 ;
234
275
235
276
for (uint8_t j=0 ; strcpy_P (convBuf, (char *)pgm_read_word (&(vType[j]))) ; j++) {
236
- if (strcmp ((char *)&str[2 ],convBuf)==0 ) { // Strip V_ and compare
277
+ // Strip V_ and compare
278
+ if (strcmp ((char *)&str[2 ], convBuf)==0 ) {
237
279
match=j;
238
280
break ;
239
281
}
@@ -245,70 +287,58 @@ void MyMQTT::processMQTTMessage(char *inputString, uint8_t inputPos) {
245
287
msg.type = match;
246
288
}
247
289
i++;
248
- } // Check if packge has payload
249
- if ((uint8_t )inputString[1 ] > (uint8_t )(inputString[3 ]+2 ) && !((uint8_t )inputString[0 ] >> 4 == MQTTSUBSCRIBE)) {
250
- strcpy (convBuf,inputString+(inputString[3 ]+4 ));
251
- msg.set (convBuf); // Payload
252
- } else {
253
- msg.set (" " ); // No payload
254
290
}
291
+
292
+ // Check if package has payload
293
+ if (mqttMsgType == MQTTPUBLISH) {
294
+ uint8_t length = (uint8_t )inputString[1 ] - (uint8_t )(inputString[3 ]+2 );
295
+ if (length && length < MAX_PAYLOAD*2 ) {
296
+ // Payload
297
+ memcpy (convBuf, inputString+(inputString[3 ]+4 ), length);
298
+ convBuf[length] = 0 ;
299
+ payload = convBuf;
300
+ }
301
+ }
302
+ msg.set (payload);
303
+
255
304
txBlink (1 );
256
305
if (!sendRoute (build (msg, GATEWAY_ADDRESS, msg.destination , msg.sensor , C_SET, msg.type , 0 ))) errBlink (1 );
257
-
258
306
}
259
307
}
260
308
261
309
void MyMQTT::SendMQTT (MyMessage &msg) {
262
310
buffsize = 0 ;
263
- if (!MQTTClientConnected) return ; // We have no connections - return
264
- if (msg.isAck ()) {
265
- Serial.println (" msg is ack!" );
266
- if (msg.sender ==255 && mGetCommand (msg)==C_INTERNAL && msg.type ==I_ID_REQUEST) {
267
- // TODO: sending ACK request on id_response fucks node up. doesn't work.
268
- // The idea was to confirm id and save to EEPROM_LATEST_NODE_ADDRESS.
269
- }
270
- } else {
271
- // we have to check every message if its a newly assigned id or not.
272
- // Ack on I_ID_RESPONSE does not work, and checking on C_PRESENTATION isn't reliable.
273
- uint8_t newNodeID = loadState (EEPROM_LATEST_NODE_ADDRESS)+1 ;
274
- if (newNodeID <= MQTT_FIRST_SENSORID) newNodeID = MQTT_FIRST_SENSORID;
275
- if (msg.sender ==newNodeID) {
276
- saveState (EEPROM_LATEST_NODE_ADDRESS,newNodeID);
277
- }
278
- if (mGetCommand (msg)==C_INTERNAL) {
279
- if (msg.type ==I_CONFIG) {
280
- txBlink (1 );
281
- if (!sendRoute (build (msg, GATEWAY_ADDRESS, msg.sender , 255 , C_INTERNAL, I_CONFIG, 0 ).set (" M" ))) errBlink (1 );
282
- } else if (msg.type ==I_ID_REQUEST && msg.sender ==255 ) {
283
- uint8_t newNodeID = loadState (EEPROM_LATEST_NODE_ADDRESS)+1 ;
284
- if (newNodeID <= MQTT_FIRST_SENSORID) newNodeID = MQTT_FIRST_SENSORID;
285
- if (newNodeID >= MQTT_LAST_SENSORID) return ; // Sorry no more id's left :(
286
- txBlink (1 );
287
- if (!sendRoute (build (msg, GATEWAY_ADDRESS, msg.sender , 255 , C_INTERNAL, I_ID_RESPONSE, 0 ).set (newNodeID))) errBlink (1 );
288
- }
289
- } else if (mGetCommand (msg)!=0 ) {
290
- if (mGetCommand (msg)==3 ) msg.type =msg.type +(S_FIRSTCUSTOM-10 ); // Special message
291
-
292
- buffer[buffsize++] = MQTTPUBLISH << 4 ; // 0:
293
- buffer[buffsize++] = 0x09 ; // 1: Remaining length with no payload, we'll set this later to correct value, buffsize -2
294
- buffer[buffsize++] = 0x00 ; // 2: Length MSB (Remaing length can never exceed ff,so MSB must be 0!)
295
- buffer[buffsize++] = 0x08 ; // 3: Length LSB (ADDR), We'll set this later
296
- if (msg.type > V_TOTAL) msg.type =V_TOTAL;// If type > defined types set to unknown.
297
- strcpy_P (buffer+4 , broker);
298
- buffsize+=strlen_P (broker);
299
- buffsize+=sprintf (&buffer[buffsize]," /%i/%i/V_%s" ,msg.sender ,msg.sensor ,getType (convBuf, &vType[msg.type ]));
300
- buffer[3 ]=buffsize-4 ; // Set correct address length on byte 4.
311
+ if (!MQTTClients) {
312
+ // We have no clients connected - return
313
+ return ;
314
+ }
315
+
316
+ if (mGetCommand (msg) == C_INTERNAL) {
317
+ // Special message
318
+ msg.type = msg.type +(S_FIRSTCUSTOM-10 );
319
+ }
320
+
321
+ buffer[buffsize++] = MQTTPUBLISH << 4 ; // 0:
322
+ buffer[buffsize++] = 0x09 ; // 1: Remaining length with no payload, we'll set this later to correct value, buffsize -2
323
+ buffer[buffsize++] = 0x00 ; // 2: Length MSB (Remaing length can never exceed ff,so MSB must be 0!)
324
+ buffer[buffsize++] = 0x08 ; // 3: Length LSB (ADDR), We'll set this later
325
+ if (msg.type > V_TOTAL) {
326
+ // If type > defined types set to unknown.
327
+ msg.type =V_TOTAL;
328
+ }
329
+ strcpy_P (buffer+4 , broker);
330
+ buffsize+=strlen_P (broker);
331
+ buffsize+=sprintf (&buffer[buffsize], " /%i/%i/V_%s" , msg.sender , msg.sensor , getType (convBuf, &vType[msg.type ]));
332
+ buffer[3 ]=buffsize-4 ; // Set correct address length on byte 4.
301
333
#ifdef DEBUG
302
- Serial.println ((char *)&buffer[4 ]);
334
+ Serial.println ((char *)&buffer[4 ]);
303
335
#endif
304
- msg.getString (convBuf);
305
- for (uint8_t a=0 ; a<strlen (convBuf); a++) {// Payload
306
- buffer[buffsize++] = convBuf[a];
307
- }
308
- buffer[1 ]=buffsize-2 ; // Set correct Remaining length on byte 2.
309
- dataCallback (buffer,&buffsize);
310
- }
336
+ msg.getString (convBuf);
337
+ for (uint8_t a=0 ; a<strlen (convBuf); a++) { // Payload
338
+ buffer[buffsize++] = convBuf[a];
311
339
}
340
+ buffer[1 ]=buffsize-2 ; // Set correct Remaining length on byte 2.
341
+ dataCallback (buffer, &buffsize);
312
342
}
313
343
314
344
void MyMQTT::rxBlink (uint8_t cnt) {
@@ -322,5 +352,3 @@ void MyMQTT::txBlink(uint8_t cnt) {
322
352
void MyMQTT::errBlink (uint8_t cnt) {
323
353
if (countErr == 255 ) { countErr = cnt; }
324
354
}
325
-
326
-
0 commit comments