Using MQTT on Dragonfly

Dependencies:   MQTT mbed mtsas

Committer:
miaotwilio
Date:
Thu Sep 14 08:14:18 2017 +0000
Revision:
8:f8a346582627
Parent:
6:4a25f3b9caef
more LEDs

Who changed what in which revision?

UserRevisionLine numberNew contents of line
miaotwilio 0:b32fa0c757d7 1 #include "MTSCellularManager.hpp"
miaotwilio 5:ded8fe5991a2 2 #include "TripDataReader.hpp"
miaotwilio 0:b32fa0c757d7 3 #include "TlsMQTTClient.hpp"
miaotwilio 0:b32fa0c757d7 4 #include "Certificates.h"
miaotwilio 8:f8a346582627 5 #include "config.example.hpp"
miaotwilio 0:b32fa0c757d7 6 #include <mbed.h>
miaotwilio 0:b32fa0c757d7 7 #include <mtsas.h>
miaotwilio 0:b32fa0c757d7 8 #include <ssl.h>
miaotwilio 0:b32fa0c757d7 9
miaotwilio 0:b32fa0c757d7 10 // This line controls the regulator's battery charger.
miaotwilio 0:b32fa0c757d7 11 // BC_NCE = 0 enables the battery charger
miaotwilio 0:b32fa0c757d7 12 // BC_NCE = 1 disables the battery charger
miaotwilio 0:b32fa0c757d7 13 DigitalOut bc_nce(PB_2);
miaotwilio 5:ded8fe5991a2 14
miaotwilio 8:f8a346582627 15 DigitalOut ledNotEntered(D7);
miaotwilio 8:f8a346582627 16 DigitalOut ledCellular(D4);
miaotwilio 8:f8a346582627 17 DigitalOut ledGPS(D5);
miaotwilio 8:f8a346582627 18 DigitalOut ledOBD(D8);
miaotwilio 8:f8a346582627 19 DigitalOut ledSendingVehicleData(D6);
miaotwilio 8:f8a346582627 20 DigitalOut ledSendingVehicleDataFailed(D3);
miaotwilio 1:5a896191c3c4 21
miaotwilio 6:4a25f3b9caef 22 static bool enableODB = false;
miaotwilio 6:4a25f3b9caef 23 static Ticker vehicleDataSamplingTicker;
miaotwilio 6:4a25f3b9caef 24 static const int VEHICLE_DATA_SAMPLING_PERIOD_MS = 50;
miaotwilio 6:4a25f3b9caef 25 static const int VEHICLE_DATA_REPORTING_PERIOD_MS = 3000;
miaotwilio 5:ded8fe5991a2 26 MTSSerial obd(D1, D0);
miaotwilio 5:ded8fe5991a2 27 static TripDataReader* pTripDataReader = NULL;
miaotwilio 5:ded8fe5991a2 28 static void vehicleDataSamplingCallback();
miaotwilio 5:ded8fe5991a2 29
miaotwilio 5:ded8fe5991a2 30 static void sendVehicleData(const MTSCellularManager::GPSStatus& gpsStatus,
miaotwilio 5:ded8fe5991a2 31 const TripDataReader::TripData& tripData);
miaotwilio 5:ded8fe5991a2 32
miaotwilio 6:4a25f3b9caef 33 static bool exitCmd = false;
miaotwilio 0:b32fa0c757d7 34
miaotwilio 0:b32fa0c757d7 35 int main() {
miaotwilio 0:b32fa0c757d7 36 // Disable the battery charger unless a battery is attached.
miaotwilio 0:b32fa0c757d7 37 bc_nce = 1;
miaotwilio 1:5a896191c3c4 38
miaotwilio 8:f8a346582627 39 ledNotEntered = 1;
miaotwilio 8:f8a346582627 40 ledCellular = 1;
miaotwilio 1:5a896191c3c4 41 ledGPS = 1;
miaotwilio 8:f8a346582627 42 ledOBD = 1;
miaotwilio 8:f8a346582627 43 ledSendingVehicleData = 1;
miaotwilio 8:f8a346582627 44 ledSendingVehicleDataFailed = 1;
miaotwilio 6:4a25f3b9caef 45
miaotwilio 0:b32fa0c757d7 46 // Change the baud rate of the debug port from the default 9600 to 115200.
miaotwilio 0:b32fa0c757d7 47 Serial debug(USBTX, USBRX);
miaotwilio 0:b32fa0c757d7 48 debug.baud(115200);
miaotwilio 0:b32fa0c757d7 49
miaotwilio 0:b32fa0c757d7 50 //Sets the log level to INFO, higher log levels produce more log output.
miaotwilio 0:b32fa0c757d7 51 //Possible levels: NONE, FATAL, ERROR, WARNING, INFO, DEBUG, TRACE
miaotwilio 0:b32fa0c757d7 52 mts::MTSLog::setLogLevel(mts::MTSLog::TRACE_LEVEL);
miaotwilio 0:b32fa0c757d7 53
miaotwilio 1:5a896191c3c4 54 logInfo("Program started");
miaotwilio 6:4a25f3b9caef 55
miaotwilio 6:4a25f3b9caef 56 logInfo("Vehicle ID: %s, TYPE: %s", VEHICLE_ID, VEHICLE_TYPE);
miaotwilio 6:4a25f3b9caef 57 if (0 == strcmp(VEHICLE_TYPE, "CAR")) {
miaotwilio 6:4a25f3b9caef 58 logInfo("Enable OBD for it is a car");
miaotwilio 6:4a25f3b9caef 59 enableODB = true;
miaotwilio 6:4a25f3b9caef 60 }
miaotwilio 6:4a25f3b9caef 61
miaotwilio 1:5a896191c3c4 62 logInfo("Initializing cellular");
miaotwilio 0:b32fa0c757d7 63 MTSCellularManager cellularManager("wireless.twilio.com");
miaotwilio 0:b32fa0c757d7 64 if (! cellularManager.init()) {
miaotwilio 0:b32fa0c757d7 65 while (true) {
miaotwilio 0:b32fa0c757d7 66 logError("failed to initialize cellular radio");
miaotwilio 0:b32fa0c757d7 67 wait(1);
miaotwilio 0:b32fa0c757d7 68 }
miaotwilio 0:b32fa0c757d7 69 }
miaotwilio 8:f8a346582627 70 ledCellular = 0;
miaotwilio 0:b32fa0c757d7 71
miaotwilio 1:5a896191c3c4 72 {
miaotwilio 1:5a896191c3c4 73 logInfo("Initializing GPS");
miaotwilio 1:5a896191c3c4 74 cellularManager.enableGps();
miaotwilio 1:5a896191c3c4 75 logInfo("GPS Initialized");
miaotwilio 1:5a896191c3c4 76 }
miaotwilio 1:5a896191c3c4 77
miaotwilio 5:ded8fe5991a2 78 TripDataReader tripDataReader(obd, ledOBD);
miaotwilio 5:ded8fe5991a2 79 pTripDataReader = &tripDataReader;
miaotwilio 6:4a25f3b9caef 80 while (enableODB) {
miaotwilio 5:ded8fe5991a2 81 logInfo("Initializing OBD");
miaotwilio 5:ded8fe5991a2 82 int r = tripDataReader.init();
miaotwilio 5:ded8fe5991a2 83 logInfo("OBD Initialization result: %d", r);
miaotwilio 5:ded8fe5991a2 84 if (0 == r) {
miaotwilio 5:ded8fe5991a2 85 logInfo("Initializing OBD sampling ticker");
miaotwilio 5:ded8fe5991a2 86 vehicleDataSamplingTicker.attach(
miaotwilio 5:ded8fe5991a2 87 &vehicleDataSamplingCallback,
miaotwilio 5:ded8fe5991a2 88 VEHICLE_DATA_SAMPLING_PERIOD_MS / 1000.);
miaotwilio 5:ded8fe5991a2 89 logInfo("OBD sampling ticker initialized");
miaotwilio 5:ded8fe5991a2 90 break;
miaotwilio 5:ded8fe5991a2 91 }
miaotwilio 5:ded8fe5991a2 92 wait_ms(100);
miaotwilio 5:ded8fe5991a2 93 }
miaotwilio 5:ded8fe5991a2 94
miaotwilio 1:5a896191c3c4 95 logInfo("Initializing CyaSSL");
miaotwilio 0:b32fa0c757d7 96 CyaSSL_Init();
miaotwilio 0:b32fa0c757d7 97
miaotwilio 1:5a896191c3c4 98 while (!exitCmd) {
miaotwilio 5:ded8fe5991a2 99 wait_ms(VEHICLE_DATA_REPORTING_PERIOD_MS);
miaotwilio 6:4a25f3b9caef 100 TripDataReader::TripData tripData;
miaotwilio 6:4a25f3b9caef 101 if (enableODB) {
miaotwilio 6:4a25f3b9caef 102 tripData = tripDataReader.getTripData();
miaotwilio 6:4a25f3b9caef 103 tripDataReader.resetAverageWindow();
miaotwilio 6:4a25f3b9caef 104 }
miaotwilio 1:5a896191c3c4 105 MTSCellularManager::GPSStatus gpsStatus = cellularManager.gpsPollStatus();
miaotwilio 1:5a896191c3c4 106 if (gpsStatus.success) {
miaotwilio 1:5a896191c3c4 107 ledGPS = 0;
miaotwilio 5:ded8fe5991a2 108 sendVehicleData(gpsStatus, tripData);
miaotwilio 1:5a896191c3c4 109 } else {
miaotwilio 1:5a896191c3c4 110 ledGPS = 1;
miaotwilio 1:5a896191c3c4 111 }
miaotwilio 1:5a896191c3c4 112 }
miaotwilio 1:5a896191c3c4 113
miaotwilio 1:5a896191c3c4 114 logInfo("Cleaning up CyaSSL");
miaotwilio 1:5a896191c3c4 115 CyaSSL_Cleanup();
miaotwilio 1:5a896191c3c4 116
miaotwilio 1:5a896191c3c4 117 logInfo("Shutting down cellular");
miaotwilio 1:5a896191c3c4 118 cellularManager.uninit();
miaotwilio 1:5a896191c3c4 119
miaotwilio 1:5a896191c3c4 120 logInfo("Program finished");
miaotwilio 1:5a896191c3c4 121 wait(1E12);
miaotwilio 1:5a896191c3c4 122 return 0;
miaotwilio 1:5a896191c3c4 123 }
miaotwilio 1:5a896191c3c4 124
miaotwilio 5:ded8fe5991a2 125 static void vehicleDataSamplingCallback() {
miaotwilio 5:ded8fe5991a2 126 pTripDataReader->sample();
miaotwilio 5:ded8fe5991a2 127 }
miaotwilio 5:ded8fe5991a2 128
miaotwilio 5:ded8fe5991a2 129 static void sendVehicleData(const MTSCellularManager::GPSStatus& gpsStatus,
miaotwilio 5:ded8fe5991a2 130 const TripDataReader::TripData& tripData) {
miaotwilio 8:f8a346582627 131 ledSendingVehicleDataFailed = 1;
miaotwilio 8:f8a346582627 132 ledSendingVehicleData = 0;
miaotwilio 1:5a896191c3c4 133
miaotwilio 1:5a896191c3c4 134 logInfo("Connecting MQTT Client");
miaotwilio 0:b32fa0c757d7 135 TlsMQTTClient client = TlsMQTTClient();
miaotwilio 0:b32fa0c757d7 136 MQTTPacket_connectData data = MQTTPacket_connectData_initializer;
miaotwilio 2:d4dcf1ebaa99 137 data.clientID.cstring = VEHICLE_ID;
miaotwilio 2:d4dcf1ebaa99 138 data.username.cstring = VEHICLE_KEY;
miaotwilio 2:d4dcf1ebaa99 139 data.password.cstring = VEHICLE_SECRET;
miaotwilio 3:0a48c984e15b 140 int result = client.connect(MQTT_GATEWAY_HOST, MQTT_GATEWAY_PORT, MQTT_GATEWAY_PROD_ROOT_CA_PEM, data);
miaotwilio 3:0a48c984e15b 141 if (MQTT::SUCCESS == result) {
miaotwilio 0:b32fa0c757d7 142 MQTT::Message message;
miaotwilio 0:b32fa0c757d7 143 char buf[512];
miaotwilio 0:b32fa0c757d7 144
miaotwilio 1:5a896191c3c4 145 logInfo("MQTT connected");
miaotwilio 0:b32fa0c757d7 146
miaotwilio 6:4a25f3b9caef 147 if (enableODB) {
miaotwilio 6:4a25f3b9caef 148 sprintf(buf, "{"
miaotwilio 6:4a25f3b9caef 149 "\"runtime\": %d,"
miaotwilio 6:4a25f3b9caef 150 "\"miles\": %d,"
miaotwilio 6:4a25f3b9caef 151 "\"speed\": %f,"
miaotwilio 6:4a25f3b9caef 152 "\"minT\": %f,"
miaotwilio 6:4a25f3b9caef 153 "\"maxT\": %f,"
miaotwilio 6:4a25f3b9caef 154 "\"avgT\": %f,"
miaotwilio 6:4a25f3b9caef 155 "\"fuel\": %d,"
miaotwilio 6:4a25f3b9caef 156 "\"brake\": %d,"
miaotwilio 6:4a25f3b9caef 157 "\"lat\": %lf,"
miaotwilio 6:4a25f3b9caef 158 "\"lon\": %lf"
miaotwilio 6:4a25f3b9caef 159 "}",
miaotwilio 5:ded8fe5991a2 160 tripData.runtime,
miaotwilio 5:ded8fe5991a2 161 tripData.distance,
miaotwilio 5:ded8fe5991a2 162 tripData.averageSpeed,
miaotwilio 5:ded8fe5991a2 163 tripData.minimumThrottle,
miaotwilio 5:ded8fe5991a2 164 tripData.maximumThrottle,
miaotwilio 5:ded8fe5991a2 165 tripData.averageThrottle,
miaotwilio 5:ded8fe5991a2 166 tripData.fuel,
miaotwilio 5:ded8fe5991a2 167 tripData.hardBrakeCount,
miaotwilio 1:5a896191c3c4 168 gpsStatus.latitudeVal,
miaotwilio 1:5a896191c3c4 169 gpsStatus.longitudeVal);
miaotwilio 6:4a25f3b9caef 170 } else {
miaotwilio 6:4a25f3b9caef 171 sprintf(buf, "{"
miaotwilio 6:4a25f3b9caef 172 "\"speed\": %f,"
miaotwilio 6:4a25f3b9caef 173 "\"lat\": %lf,"
miaotwilio 6:4a25f3b9caef 174 "\"lon\": %lf"
miaotwilio 6:4a25f3b9caef 175 "}",
miaotwilio 6:4a25f3b9caef 176 gpsStatus.speedVal,
miaotwilio 6:4a25f3b9caef 177 gpsStatus.latitudeVal,
miaotwilio 6:4a25f3b9caef 178 gpsStatus.longitudeVal);
miaotwilio 6:4a25f3b9caef 179 }
miaotwilio 6:4a25f3b9caef 180
miaotwilio 0:b32fa0c757d7 181 message.qos = MQTT::QOS1;
miaotwilio 0:b32fa0c757d7 182 message.payload = (void*)buf;
miaotwilio 0:b32fa0c757d7 183 message.payloadlen = strlen(buf) + 1;
miaotwilio 1:5a896191c3c4 184 logInfo("MQTT message publishing buf: %s", buf);
miaotwilio 2:d4dcf1ebaa99 185 int rc = client.publish("sync/lists/vehicle-" VEHICLE_ID "-data", message);
miaotwilio 1:5a896191c3c4 186 logInfo("MQTT message publish result: %d", rc);
miaotwilio 0:b32fa0c757d7 187
miaotwilio 1:5a896191c3c4 188 logInfo("MQTT disconnecting");
miaotwilio 0:b32fa0c757d7 189 client.disconnect();
miaotwilio 3:0a48c984e15b 190 } else {
miaotwilio 8:f8a346582627 191 ledSendingVehicleDataFailed = 0;
miaotwilio 3:0a48c984e15b 192 logError("MQTT connection failed %d", result);
miaotwilio 0:b32fa0c757d7 193 }
miaotwilio 8:f8a346582627 194 ledSendingVehicleData = 1;
miaotwilio 1:5a896191c3c4 195 }
miaotwilio 0:b32fa0c757d7 196
miaotwilio 1:5a896191c3c4 197 /*
miaotwilio 1:5a896191c3c4 198 static void subscribeToTest2() {
miaotwilio 1:5a896191c3c4 199 rc = client.subscribe("sync/lists/test2", MQTT::QOS1, test2Handler);
miaotwilio 1:5a896191c3c4 200 logInfo("MQTT subscription result: %d", rc);
miaotwilio 0:b32fa0c757d7 201 }
miaotwilio 0:b32fa0c757d7 202
miaotwilio 0:b32fa0c757d7 203 static void test2Handler(MQTT::MessageData& data) {
miaotwilio 0:b32fa0c757d7 204 static const size_t MAX_DISPLAY_MESSAGE_SIZE = 30;
miaotwilio 0:b32fa0c757d7 205 char buf[MAX_DISPLAY_MESSAGE_SIZE + 1];
miaotwilio 0:b32fa0c757d7 206 if (data.message.payloadlen <= MAX_DISPLAY_MESSAGE_SIZE) {
miaotwilio 0:b32fa0c757d7 207 strncpy(buf, (char*)data.message.payload, data.message.payloadlen);
miaotwilio 0:b32fa0c757d7 208 buf[data.message.payloadlen] = '\0';
miaotwilio 0:b32fa0c757d7 209 } else {
miaotwilio 0:b32fa0c757d7 210 strncpy(buf, (char*)data.message.payload, MAX_DISPLAY_MESSAGE_SIZE - 3);
miaotwilio 0:b32fa0c757d7 211 buf[MAX_DISPLAY_MESSAGE_SIZE-3] = '.';
miaotwilio 0:b32fa0c757d7 212 buf[MAX_DISPLAY_MESSAGE_SIZE-2] = '.';
miaotwilio 0:b32fa0c757d7 213 buf[MAX_DISPLAY_MESSAGE_SIZE-1] = '.';
miaotwilio 0:b32fa0c757d7 214 buf[MAX_DISPLAY_MESSAGE_SIZE] = '\0';
miaotwilio 0:b32fa0c757d7 215 }
miaotwilio 0:b32fa0c757d7 216 logDebug("topic %s payload received len %d data %s", data.topicName.lenstring.data, data.message.payloadlen, buf);
miaotwilio 0:b32fa0c757d7 217
miaotwilio 0:b32fa0c757d7 218 // sync client can send binary data using payload format:
miaotwilio 0:b32fa0c757d7 219 // {
miaotwilio 0:b32fa0c757d7 220 // "payload": "ZXhpdA==", # base64 encoded "exit"
miaotwilio 0:b32fa0c757d7 221 // "_iot_meta": {
miaotwilio 0:b32fa0c757d7 222 // "payload_encoding": "base64",
miaotwilio 0:b32fa0c757d7 223 // "payload_type": "application/octet-stream",
miaotwilio 0:b32fa0c757d7 224 // }
miaotwilio 0:b32fa0c757d7 225 // }
miaotwilio 0:b32fa0c757d7 226 if (0 == strncmp((char*)data.message.payload, "exit", data.message.payloadlen)) {
miaotwilio 0:b32fa0c757d7 227 exitCmd = true;
miaotwilio 0:b32fa0c757d7 228 }
miaotwilio 1:5a896191c3c4 229 }*/