iot_water_monitor_v2

Dependencies:   easy-connect-v16 Watchdog FP MQTTPacket RecordType-v-16 watersenor_and_temp_code

Committer:
DuyLionTran
Date:
Tue Dec 12 17:53:40 2017 +0000
Revision:
17:b89d884eb609
version 1.6: Project is re-organized, RTC is added, Sensor Calibration and Flash is being developed

Who changed what in which revision?

UserRevisionLine numberNew contents of line
DuyLionTran 17:b89d884eb609 1 #ifndef __SIMPLEMQTT_H__
DuyLionTran 17:b89d884eb609 2 #define __SIMPLEMQTT_H__
DuyLionTran 17:b89d884eb609 3
DuyLionTran 17:b89d884eb609 4 /***************************************************************
DuyLionTran 17:b89d884eb609 5 * Includes
DuyLionTran 17:b89d884eb609 6 ***************************************************************/
DuyLionTran 17:b89d884eb609 7 #include "easy-connect.h"
DuyLionTran 17:b89d884eb609 8 #include "MQTTClient.h"
DuyLionTran 17:b89d884eb609 9 #include "NDefLib/NDefNfcTag.h"
DuyLionTran 17:b89d884eb609 10 #include "NDefLib/RecordType/RecordURI.h"
DuyLionTran 17:b89d884eb609 11 #include "MQTTNetwork.h"
DuyLionTran 17:b89d884eb609 12 #include "MQTTmbed.h"
DuyLionTran 17:b89d884eb609 13
DuyLionTran 17:b89d884eb609 14 /***************************************************************
DuyLionTran 17:b89d884eb609 15 * Definitions
DuyLionTran 17:b89d884eb609 16 ***************************************************************/
DuyLionTran 17:b89d884eb609 17 // Configuration values needed to connect to IBM IoT Cloud
DuyLionTran 17:b89d884eb609 18 #define ORG MQTT_ORG_ID // connect to ORG.internetofthings.ibmcloud.com/ For a registered connection, replace with your org
DuyLionTran 17:b89d884eb609 19 #define ID MQTT_DEVICE_ID // For a registered connection is your device id
DuyLionTran 17:b89d884eb609 20 #define AUTH_TOKEN MQTT_DEVICE_PASSWORD // For a registered connection is a device auth-token
DuyLionTran 17:b89d884eb609 21 #define DEFAULT_TYPE_NAME MQTT_DEVICE_TYPE // For a registered connection is device type
DuyLionTran 17:b89d884eb609 22 #define AUTH_METHOD MQTT_USERNAME
DuyLionTran 17:b89d884eb609 23
DuyLionTran 17:b89d884eb609 24 #define TYPE DEFAULT_TYPE_NAME // For a registered connection, replace with your type
DuyLionTran 17:b89d884eb609 25 #define IBM_IOT_PORT MQTT_PORT
DuyLionTran 17:b89d884eb609 26
DuyLionTran 17:b89d884eb609 27 #define MQTT_MAX_PACKET_SIZE 400
DuyLionTran 17:b89d884eb609 28 #define MQTT_MAX_PAYLOAD_SIZE 300
DuyLionTran 17:b89d884eb609 29
DuyLionTran 17:b89d884eb609 30 /***************************************************************
DuyLionTran 17:b89d884eb609 31 * Variables
DuyLionTran 17:b89d884eb609 32 ***************************************************************/
DuyLionTran 17:b89d884eb609 33 char *projectName = "WaterMonitor";
DuyLionTran 17:b89d884eb609 34 static char id[30] = ID; // mac without colons
DuyLionTran 17:b89d884eb609 35 static char org[12] = ORG;
DuyLionTran 17:b89d884eb609 36 static char type[30] = TYPE;
DuyLionTran 17:b89d884eb609 37 static char auth_token[30] = AUTH_TOKEN; // Auth_token is only used in non-quickstart mode
DuyLionTran 17:b89d884eb609 38 static int connack_rc = 0; // MQTT connack return code
DuyLionTran 17:b89d884eb609 39 static bool netConnecting = false;
DuyLionTran 17:b89d884eb609 40 static bool mqttConnecting = false;
DuyLionTran 17:b89d884eb609 41 static bool netConnected = false;
DuyLionTran 17:b89d884eb609 42 static bool connected = false;
DuyLionTran 17:b89d884eb609 43 static int retryAttempt = 0;
DuyLionTran 17:b89d884eb609 44 static int connectTimeout = 1000;
DuyLionTran 17:b89d884eb609 45 static char subscription_url[MQTT_MAX_PAYLOAD_SIZE];
DuyLionTran 17:b89d884eb609 46
DuyLionTran 17:b89d884eb609 47 /***************************************************************
DuyLionTran 17:b89d884eb609 48 * Unity function definitions
DuyLionTran 17:b89d884eb609 49 ***************************************************************/
DuyLionTran 17:b89d884eb609 50 /** brief Callback function when MQTT message arrives
DuyLionTran 17:b89d884eb609 51 * param[in] msgMQTT
DuyLionTran 17:b89d884eb609 52 * retral None
DuyLionTran 17:b89d884eb609 53 */
DuyLionTran 17:b89d884eb609 54 void MQTT_SubscribeCallback(MQTT::MessageData & msgMQTT);
DuyLionTran 17:b89d884eb609 55
DuyLionTran 17:b89d884eb609 56 /** brief Subscribe to a MQTT topic and set the MQTT callback function
DuyLionTran 17:b89d884eb609 57 * param[in] subscribeTopic Topic to be subscribed
DuyLionTran 17:b89d884eb609 58 * param[in] client MQTT client
DuyLionTran 17:b89d884eb609 59 * retral returnCode from MQTTClient.h
DuyLionTran 17:b89d884eb609 60 */
DuyLionTran 17:b89d884eb609 61 int MQTT_Subscribe(char *subscribeTopic, MQTT::Client<MQTTNetwork, Countdown, MQTT_MAX_PACKET_SIZE>* client);
DuyLionTran 17:b89d884eb609 62
DuyLionTran 17:b89d884eb609 63 /** brief Connect to the internet then the MQTT network
DuyLionTran 17:b89d884eb609 64 * param[in] client MQTT client
DuyLionTran 17:b89d884eb609 65 * param[in] mqttNetwork MQTT network
DuyLionTran 17:b89d884eb609 66 * param[in] network The internet network interface (ethernet, wifi...)
DuyLionTran 17:b89d884eb609 67 * retral Internet connect result and returnCode from MQTTClient.h
DuyLionTran 17:b89d884eb609 68 */
DuyLionTran 17:b89d884eb609 69 int MQTT_Connect(MQTT::Client<MQTTNetwork, Countdown, MQTT_MAX_PACKET_SIZE>* client, MQTTNetwork *mqttNetwork, NetworkInterface* network);
DuyLionTran 17:b89d884eb609 70
DuyLionTran 17:b89d884eb609 71 /** brief Setup the number of attempt to re-connect to the internet
DuyLionTran 17:b89d884eb609 72 * param[in] attemptNumber The number of attemp
DuyLionTran 17:b89d884eb609 73 */
DuyLionTran 17:b89d884eb609 74 int MQTT_GetConnTimeout(int attemptNumber);
DuyLionTran 17:b89d884eb609 75 void MQTT_AttemptConnect(MQTT::Client<MQTTNetwork, Countdown, MQTT_MAX_PACKET_SIZE>* client, MQTTNetwork *mqttNetwork, NetworkInterface* network);
DuyLionTran 17:b89d884eb609 76
DuyLionTran 17:b89d884eb609 77 /** brief Connect to the internet then the MQTT network
DuyLionTran 17:b89d884eb609 78 * param[in] client MQTT client
DuyLionTran 17:b89d884eb609 79 * param[in] inputTime The time when the data is attempt to be sent
DuyLionTran 17:b89d884eb609 80 * param[in] commandID Sequence number of the frame
DuyLionTran 17:b89d884eb609 81 * param[in] adcVal_0 The ADC value to be sent
DuyLionTran 17:b89d884eb609 82 * retral returnCode from MQTTClient.h
DuyLionTran 17:b89d884eb609 83 */
DuyLionTran 17:b89d884eb609 84 int MQTT_PublishADC(MQTT::Client<MQTTNetwork, Countdown, MQTT_MAX_PACKET_SIZE>* client, time_t inputTime, uint16_t commandID, float adcVal_0);
DuyLionTran 17:b89d884eb609 85
DuyLionTran 17:b89d884eb609 86 /***************************************************************
DuyLionTran 17:b89d884eb609 87 * Unity function declarations
DuyLionTran 17:b89d884eb609 88 ***************************************************************/
DuyLionTran 17:b89d884eb609 89 void MQTT_SubscribeCallback(MQTT::MessageData & msgMQTT) {
DuyLionTran 17:b89d884eb609 90 char msg[MQTT_MAX_PAYLOAD_SIZE];
DuyLionTran 17:b89d884eb609 91 msg[0]='\0';
DuyLionTran 17:b89d884eb609 92 strncat (msg, (char*)msgMQTT.message.payload, msgMQTT.message.payloadlen);
DuyLionTran 17:b89d884eb609 93 printf ("--->>> MQTT_SubscribeCallback msg: %s\n\r", msg);
DuyLionTran 17:b89d884eb609 94 }
DuyLionTran 17:b89d884eb609 95
DuyLionTran 17:b89d884eb609 96 int MQTT_Subscribe(char *subscribeTopic, MQTT::Client<MQTTNetwork, Countdown, MQTT_MAX_PACKET_SIZE>* client) {
DuyLionTran 17:b89d884eb609 97 return client->subscribe(subscribeTopic, MQTT::QOS1, MQTT_SubscribeCallback);
DuyLionTran 17:b89d884eb609 98 }
DuyLionTran 17:b89d884eb609 99
DuyLionTran 17:b89d884eb609 100 int MQTT_Connect(MQTT::Client<MQTTNetwork, Countdown, MQTT_MAX_PACKET_SIZE>* client, MQTTNetwork *mqttNetwork, NetworkInterface* network) {
DuyLionTran 17:b89d884eb609 101 const char* iot_ibm = MQTT_BROKER_URL;
DuyLionTran 17:b89d884eb609 102 char hostname[strlen(org) + strlen(iot_ibm) + 1];
DuyLionTran 17:b89d884eb609 103
DuyLionTran 17:b89d884eb609 104 sprintf(hostname, "%s%s", org, iot_ibm);
DuyLionTran 17:b89d884eb609 105 // Construct clientId - d:org:type:id
DuyLionTran 17:b89d884eb609 106 char clientId[strlen(org) + strlen(type) + strlen(id) + 5];
DuyLionTran 17:b89d884eb609 107 sprintf(clientId, "d:%s:%s:%s", org, type, id);
DuyLionTran 17:b89d884eb609 108 sprintf(subscription_url, "%s.%s/#/device/%s/%s/", org, "internetofthings.ibmcloud.com", id, DEFAULT_TYPE_NAME);
DuyLionTran 17:b89d884eb609 109
DuyLionTran 17:b89d884eb609 110 // Network debug statements
DuyLionTran 17:b89d884eb609 111 LOG("=====================================\n\r");
DuyLionTran 17:b89d884eb609 112 LOG("Nucleo IP ADDRESS: %s\n\r", network->get_ip_address());
DuyLionTran 17:b89d884eb609 113 LOG("Nucleo MAC ADDRESS: %s\n\r", network->get_mac_address());
DuyLionTran 17:b89d884eb609 114 LOG("Server Hostname: %s port: %d\n\r", hostname, IBM_IOT_PORT);
DuyLionTran 17:b89d884eb609 115 LOG("Client ID: %s\n\r", clientId);
DuyLionTran 17:b89d884eb609 116 LOG("Topic: %s\n\r",MQTT_EVENT_TOPIC);
DuyLionTran 17:b89d884eb609 117 LOG("Subscription URL: %s\n\r", subscription_url);
DuyLionTran 17:b89d884eb609 118 LOG("=====================================\n\r");
DuyLionTran 17:b89d884eb609 119 netConnecting = true;
DuyLionTran 17:b89d884eb609 120 int rc = mqttNetwork->connect(hostname, IBM_IOT_PORT);
DuyLionTran 17:b89d884eb609 121 if (rc != 0) {
DuyLionTran 17:b89d884eb609 122 printf("rc from TCP connect is %d\r\n", rc);
DuyLionTran 17:b89d884eb609 123 return rc;
DuyLionTran 17:b89d884eb609 124 }
DuyLionTran 17:b89d884eb609 125
DuyLionTran 17:b89d884eb609 126 printf ("--->TCP Connected\n\r");
DuyLionTran 17:b89d884eb609 127 netConnected = true;
DuyLionTran 17:b89d884eb609 128 netConnecting = false;
DuyLionTran 17:b89d884eb609 129
DuyLionTran 17:b89d884eb609 130 // MQTT Connect
DuyLionTran 17:b89d884eb609 131 mqttConnecting = true;
DuyLionTran 17:b89d884eb609 132 MQTTPacket_connectData data = MQTTPacket_connectData_initializer;
DuyLionTran 17:b89d884eb609 133 data.MQTTVersion = 4;
DuyLionTran 17:b89d884eb609 134 data.struct_version = 0;
DuyLionTran 17:b89d884eb609 135 data.clientID.cstring = clientId;
DuyLionTran 17:b89d884eb609 136 data.keepAliveInterval = MQTT_KEEPALIVE; // in Sec
DuyLionTran 17:b89d884eb609 137 data.username.cstring = AUTH_METHOD;
DuyLionTran 17:b89d884eb609 138 data.password.cstring = auth_token;
DuyLionTran 17:b89d884eb609 139 printf ("AutToken: %s\n\r", auth_token);
DuyLionTran 17:b89d884eb609 140
DuyLionTran 17:b89d884eb609 141 if ((rc = client->connect(data)) != 0) {
DuyLionTran 17:b89d884eb609 142 printf("rc from MQTT connect is %d\r\n", rc);
DuyLionTran 17:b89d884eb609 143 connack_rc = rc;
DuyLionTran 17:b89d884eb609 144 return rc;
DuyLionTran 17:b89d884eb609 145 }
DuyLionTran 17:b89d884eb609 146 connected = true;
DuyLionTran 17:b89d884eb609 147 printf ("--->MQTT Connected\n\r");
DuyLionTran 17:b89d884eb609 148 if ((rc = MQTT_Subscribe(MQTT_COMMAND_TOPIC, client)) == 0) {
DuyLionTran 17:b89d884eb609 149 LOG ("--->>>MQTT subscribed to: %s\n\r", MQTT_COMMAND_TOPIC);
DuyLionTran 17:b89d884eb609 150 } else {
DuyLionTran 17:b89d884eb609 151 LOG ("--->>>ERROR MQTT subscribe : %s\n\r", MQTT_COMMAND_TOPIC);
DuyLionTran 17:b89d884eb609 152 }
DuyLionTran 17:b89d884eb609 153 mqttConnecting = false;
DuyLionTran 17:b89d884eb609 154 connack_rc = rc;
DuyLionTran 17:b89d884eb609 155 return rc;
DuyLionTran 17:b89d884eb609 156 }
DuyLionTran 17:b89d884eb609 157
DuyLionTran 17:b89d884eb609 158
DuyLionTran 17:b89d884eb609 159 int MQTT_GetConnTimeout(int attemptNumber) { // First 10 attempts try within 3 seconds, next 10 attempts retry after every 1 minute
DuyLionTran 17:b89d884eb609 160 // after 20 attempts, retry every 10 minutes
DuyLionTran 17:b89d884eb609 161 return (attemptNumber < 10) ? 3 : (attemptNumber < 20) ? 60 : 600;
DuyLionTran 17:b89d884eb609 162 }
DuyLionTran 17:b89d884eb609 163
DuyLionTran 17:b89d884eb609 164
DuyLionTran 17:b89d884eb609 165 void MQTT_AttemptConnect(MQTT::Client<MQTTNetwork, Countdown, MQTT_MAX_PACKET_SIZE>* client, MQTTNetwork *mqttNetwork, NetworkInterface* network) {
DuyLionTran 17:b89d884eb609 166 connected = false;
DuyLionTran 17:b89d884eb609 167
DuyLionTran 17:b89d884eb609 168 while (MQTT_Connect(client, mqttNetwork, network) != MQTT_CONNECTION_ACCEPTED) {
DuyLionTran 17:b89d884eb609 169 if (connack_rc == MQTT_NOT_AUTHORIZED || connack_rc == MQTT_BAD_USERNAME_OR_PASSWORD) {
DuyLionTran 17:b89d884eb609 170 printf ("File: %s, Line: %d Error: %d\n\r",__FILE__,__LINE__, connack_rc);
DuyLionTran 17:b89d884eb609 171 return; // don't reattempt to connect if credentials are wrong
DuyLionTran 17:b89d884eb609 172 }
DuyLionTran 17:b89d884eb609 173 int timeout = MQTT_GetConnTimeout(++retryAttempt);
DuyLionTran 17:b89d884eb609 174 WARN("Retry attempt number %d waiting %d\n", retryAttempt, timeout);
DuyLionTran 17:b89d884eb609 175
DuyLionTran 17:b89d884eb609 176 // if ipstack and client were on the heap we could deconstruct and goto a label where they are constructed
DuyLionTran 17:b89d884eb609 177 // or maybe just add the proper members to do this disconnect and call MQTT_AttemptConnect(...)
DuyLionTran 17:b89d884eb609 178 // this works - reset the system when the retry count gets to a threshold
DuyLionTran 17:b89d884eb609 179 if (retryAttempt == 5)
DuyLionTran 17:b89d884eb609 180 NVIC_SystemReset();
DuyLionTran 17:b89d884eb609 181 else
DuyLionTran 17:b89d884eb609 182 wait(timeout);
DuyLionTran 17:b89d884eb609 183 }
DuyLionTran 17:b89d884eb609 184 }
DuyLionTran 17:b89d884eb609 185
DuyLionTran 17:b89d884eb609 186 int MQTT_PublishADC(MQTT::Client<MQTTNetwork, Countdown, MQTT_MAX_PACKET_SIZE>* client, time_t inputTime, uint16_t commandID, float adcVal_0) {
DuyLionTran 17:b89d884eb609 187 MQTT::Message message;
DuyLionTran 17:b89d884eb609 188 const char* pubTopic = MQTT_EVENT_TOPIC;
DuyLionTran 17:b89d884eb609 189
DuyLionTran 17:b89d884eb609 190 char buf[MQTT_MAX_PAYLOAD_SIZE];
DuyLionTran 17:b89d884eb609 191 char timeBuf[50];
DuyLionTran 17:b89d884eb609 192
DuyLionTran 17:b89d884eb609 193 if (!client->isConnected()) {
DuyLionTran 17:b89d884eb609 194 printf ("---> MQTT DISCONNECTED\n\r"); return MQTT::FAILURE;
DuyLionTran 17:b89d884eb609 195 }
DuyLionTran 17:b89d884eb609 196
DuyLionTran 17:b89d884eb609 197 strftime(timeBuf, 50, "%Y/%m/%d %H:%M:%S", localtime(&inputTime));
DuyLionTran 17:b89d884eb609 198 sprintf(buf,
DuyLionTran 17:b89d884eb609 199 "{\"Project\":\"%s\",\"Time\":\"%s\",\"Type\":1,\"cmdID\":%d,\"ADC0\":%0.2f}",
DuyLionTran 17:b89d884eb609 200 projectName, timeBuf, commandID, adcVal_0);
DuyLionTran 17:b89d884eb609 201 message.qos = MQTT::QOS0;
DuyLionTran 17:b89d884eb609 202 message.retained = false;
DuyLionTran 17:b89d884eb609 203 message.dup = false;
DuyLionTran 17:b89d884eb609 204 message.payload = (void*)buf;
DuyLionTran 17:b89d884eb609 205 message.payloadlen = strlen(buf);
DuyLionTran 17:b89d884eb609 206
DuyLionTran 17:b89d884eb609 207 if((message.payloadlen + strlen(pubTopic)+1) >= MQTT_MAX_PACKET_SIZE)
DuyLionTran 17:b89d884eb609 208 printf("message too long!\r\n");
DuyLionTran 17:b89d884eb609 209
DuyLionTran 17:b89d884eb609 210 LOG("Publishing %s\n\r", buf);
DuyLionTran 17:b89d884eb609 211 return client->publish(pubTopic, message);
DuyLionTran 17:b89d884eb609 212 }
DuyLionTran 17:b89d884eb609 213 #endif /* __SIMPLEMQTT_H__ */