Connecting a Multi-Tech Systems Dragonfly™ to Twilio's Sync for IoT Quickstart. Blink a dev board LED.
Dependencies: MQTT MbedJSONValue mbed mtsas
Fork of DragonflyMQTT by
Code to connect a Multi-Tech® MultiConnect® Dragonfly™ to Twilio's Sync for IoT: https://www.twilio.com/docs/api/devices
Uses MQTT over TLS and subscribes to a topic where you can control an LED. See also our Quickstart using this code, here: https://www.twilio.com/docs/quickstart/sync-iot/mqtt-multi-tech-multiconnect-dragonfly-sync-iot
main.cpp
- Committer:
- miaotwilio
- Date:
- 2017-09-05
- Revision:
- 5:ded8fe5991a2
- Parent:
- 3:0a48c984e15b
- Child:
- 6:4a25f3b9caef
File content as of revision 5:ded8fe5991a2:
#include "MTSCellularManager.hpp" #include "TripDataReader.hpp" #include "TlsMQTTClient.hpp" #include "Certificates.h" #include "config.hpp" #include <mbed.h> #include <mtsas.h> #include <ssl.h> // This line controls the regulator's battery charger. // BC_NCE = 0 enables the battery charger // BC_NCE = 1 disables the battery charger DigitalOut bc_nce(PB_2); DigitalOut ledMQTTYield(D5); DigitalOut ledGPS(D8); MTSSerial obd(D1, D0); DigitalOut ledOBD(D6); static const int VEHICLE_DATA_SAMPLING_PERIOD_MS = 50; static Ticker vehicleDataSamplingTicker; static TripDataReader* pTripDataReader = NULL; static void vehicleDataSamplingCallback(); static const int VEHICLE_DATA_REPORTING_PERIOD_MS = 3000; static bool exitCmd = false; static void sendVehicleData(const MTSCellularManager::GPSStatus& gpsStatus, const TripDataReader::TripData& tripData); //static void test2Handler(MQTT::MessageData& data); int main() { // Disable the battery charger unless a battery is attached. bc_nce = 1; ledMQTTYield = 1; ledGPS = 1; // Change the baud rate of the debug port from the default 9600 to 115200. Serial debug(USBTX, USBRX); debug.baud(115200); //Sets the log level to INFO, higher log levels produce more log output. //Possible levels: NONE, FATAL, ERROR, WARNING, INFO, DEBUG, TRACE mts::MTSLog::setLogLevel(mts::MTSLog::TRACE_LEVEL); logInfo("Program started"); logInfo("Initializing cellular"); MTSCellularManager cellularManager("wireless.twilio.com"); if (! cellularManager.init()) { while (true) { logError("failed to initialize cellular radio"); wait(1); } } { logInfo("Initializing GPS"); cellularManager.enableGps(); logInfo("GPS Initialized"); } TripDataReader tripDataReader(obd, ledOBD); pTripDataReader = &tripDataReader; while (true) { logInfo("Initializing OBD"); int r = tripDataReader.init(); logInfo("OBD Initialization result: %d", r); if (0 == r) { logInfo("Initializing OBD sampling ticker"); vehicleDataSamplingTicker.attach( &vehicleDataSamplingCallback, VEHICLE_DATA_SAMPLING_PERIOD_MS / 1000.); logInfo("OBD sampling ticker initialized"); break; } wait_ms(100); } logInfo("Initializing CyaSSL"); CyaSSL_Init(); while (!exitCmd) { wait_ms(VEHICLE_DATA_REPORTING_PERIOD_MS); TripDataReader::TripData tripData = tripDataReader.getTripData(); tripDataReader.resetAverageWindow(); MTSCellularManager::GPSStatus gpsStatus = cellularManager.gpsPollStatus(); if (gpsStatus.success) { ledGPS = 0; sendVehicleData(gpsStatus, tripData); } else { ledGPS = 1; } } logInfo("Cleaning up CyaSSL"); CyaSSL_Cleanup(); logInfo("Shutting down cellular"); cellularManager.uninit(); logInfo("Program finished"); wait(1E12); return 0; } static void vehicleDataSamplingCallback() { pTripDataReader->sample(); } static void sendVehicleData(const MTSCellularManager::GPSStatus& gpsStatus, const TripDataReader::TripData& tripData) { ledMQTTYield = 0; logInfo("Connecting MQTT Client"); TlsMQTTClient client = TlsMQTTClient(); MQTTPacket_connectData data = MQTTPacket_connectData_initializer; data.clientID.cstring = VEHICLE_ID; data.username.cstring = VEHICLE_KEY; data.password.cstring = VEHICLE_SECRET; int result = client.connect(MQTT_GATEWAY_HOST, MQTT_GATEWAY_PORT, MQTT_GATEWAY_PROD_ROOT_CA_PEM, data); if (MQTT::SUCCESS == result) { MQTT::Message message; char buf[512]; logInfo("MQTT connected"); sprintf(buf, "{" "\"driver_id\": %s," "\"runtime\": %d," "\"miles\": %d," "\"speed\": %f," "\"minT\": %f," "\"maxT\": %f," "\"avgT\": %f," "\"fuel\": %d," "\"brake\": %d," "\"lat\": %lf," "\"lon\": %lf" "}", VEHICLE_ID, tripData.runtime, tripData.distance, tripData.averageSpeed, tripData.minimumThrottle, tripData.maximumThrottle, tripData.averageThrottle, tripData.fuel, tripData.hardBrakeCount, gpsStatus.latitudeVal, gpsStatus.longitudeVal); message.qos = MQTT::QOS1; message.payload = (void*)buf; message.payloadlen = strlen(buf) + 1; logInfo("MQTT message publishing buf: %s", buf); int rc = client.publish("sync/lists/vehicle-" VEHICLE_ID "-data", message); logInfo("MQTT message publish result: %d", rc); logInfo("MQTT disconnecting"); client.disconnect(); } else { logError("MQTT connection failed %d", result); } ledMQTTYield = 1; } /* static void subscribeToTest2() { rc = client.subscribe("sync/lists/test2", MQTT::QOS1, test2Handler); logInfo("MQTT subscription result: %d", rc); } static void test2Handler(MQTT::MessageData& data) { static const size_t MAX_DISPLAY_MESSAGE_SIZE = 30; char buf[MAX_DISPLAY_MESSAGE_SIZE + 1]; if (data.message.payloadlen <= MAX_DISPLAY_MESSAGE_SIZE) { strncpy(buf, (char*)data.message.payload, data.message.payloadlen); buf[data.message.payloadlen] = '\0'; } else { strncpy(buf, (char*)data.message.payload, MAX_DISPLAY_MESSAGE_SIZE - 3); buf[MAX_DISPLAY_MESSAGE_SIZE-3] = '.'; buf[MAX_DISPLAY_MESSAGE_SIZE-2] = '.'; buf[MAX_DISPLAY_MESSAGE_SIZE-1] = '.'; buf[MAX_DISPLAY_MESSAGE_SIZE] = '\0'; } logDebug("topic %s payload received len %d data %s", data.topicName.lenstring.data, data.message.payloadlen, buf); // sync client can send binary data using payload format: // { // "payload": "ZXhpdA==", # base64 encoded "exit" // "_iot_meta": { // "payload_encoding": "base64", // "payload_type": "application/octet-stream", // } // } if (0 == strncmp((char*)data.message.payload, "exit", data.message.payloadlen)) { exitCmd = true; } }*/