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

Files at this revision

API Documentation at this revision

Comitter:
SomeRandomBloke
Date:
Tue May 01 21:43:40 2012 +0000
Parent:
3:f19f9c62c00b
Child:
5:0dbc27a7af55
Commit message:
Added output module for Sen.Se and emonCMS

Changed in this revision

Outputs/OutputDef.h Show annotated file Show diff for this revision Revisions of this file
Outputs/OutputEmonCms.cpp Show annotated file Show diff for this revision Revisions of this file
Outputs/OutputEmonCms.h Show annotated file Show diff for this revision Revisions of this file
Outputs/OutputPachube.cpp Show annotated file Show diff for this revision Revisions of this file
Outputs/OutputPachube.h Show annotated file Show diff for this revision Revisions of this file
Outputs/OutputSenSe.cpp Show annotated file Show diff for this revision Revisions of this file
Outputs/OutputSenSe.h Show annotated file Show diff for this revision Revisions of this file
Routing/IoTRouting.cpp Show annotated file Show diff for this revision Revisions of this file
Routing/IoTRouting.h Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
--- a/Outputs/OutputDef.h	Fri Apr 20 19:32:34 2012 +0000
+++ b/Outputs/OutputDef.h	Tue May 01 21:43:40 2012 +0000
@@ -45,7 +45,7 @@
 
     /** Initialise output definition object
      */
-    virtual void init() = 0;
+    virtual void init( ) = 0;
     
     /** Add a character pointer reading to output 
      * 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Outputs/OutputEmonCms.cpp	Tue May 01 21:43:40 2012 +0000
@@ -0,0 +1,106 @@
+/** IoT Gateway Output definition for Open Energy Monitor emonCms 
+ *
+ * @author Andrew Lindsay
+ *
+ * @section LICENSE
+ *
+ * Copyright (c) 2012 Andrew Lindsay (andrew [at] thiseldo [dot] co [dot] uk)
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ * 
+ * @section DESCRIPTION
+ * 
+ * API URL: http://host/emoncms/api/post?apikey=key&json={power:252.4}
+ ,temperature:15.4}
+ * 
+ */
+
+#include "mbed.h"
+#include "OutputEmonCms.h"
+
+DigitalOut emonActivityLED(p29, "activityLED");
+
+// Constructor
+OutputEmonCms::OutputEmonCms() {
+    sendCount = 0;
+}
+
+/** Alternative Constructor
+  */
+OutputEmonCms::OutputEmonCms( char *internalBufferStart, char *url, char *key ) {
+    sendCount = 0;
+    dataBuffer = internalBufferStart;
+    apiUrl = url;
+    apiKey = key;
+    // Setup start of URL buffer
+    init();
+}
+
+
+void OutputEmonCms::init( ) {
+    dbufPtr = dataBuffer;
+    sprintf(dataBuffer, apiUrl, apiKey );
+    dbufPtr = dataBuffer + strlen(dataBuffer);
+    *dbufPtr = '\0';
+    hasData = false;
+}
+
+// Datafeed us the name of the value
+void OutputEmonCms::addReading(char *dataFeed, char *dataStream, char *reading ) {
+
+    snprintf(dbufPtr, DATABUF_SIZE, "{%s:%s}\0", dataFeed, reading);
+    hasData = true;
+    send();
+}
+
+
+int OutputEmonCms::send( void ) {
+//    char urlBuf[64];
+    HTTPClient http;
+
+    if ( hasData && strlen( dataBuffer ) > 1 ) {
+
+        HTTPText csvContent("application/json");
+        csvContent.set(std::string(dataBuffer));
+
+        // uri for post includes feed ID and datastream ID
+        printf("URL: %s\n",dataBuffer);
+
+
+        emonActivityLED = 1;
+        // result should be 0 and response should be 200 for successful post
+        printf("EmonCms send count %d\n", ++sendCount);
+/*
+        printf("\nHEAP STATS\n");
+        __heapstats((__heapprt)fprintf,stderr);
+        printf("\nHEAP CHECK\n");
+        __heapvalid((__heapprt)fprintf,stderr, 0);
+        printf("\nStackP: %ld\n",__current_sp());
+        printf("---------------\n");
+*/
+        HTTPResult result = http.get(dataBuffer, NULL);
+        int response = http.getHTTPResponseCode();
+        printf("updateDataStream(%d)\n", response );
+        emonActivityLED = 0;
+    }
+
+    init();
+    return 0;
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Outputs/OutputEmonCms.h	Tue May 01 21:43:40 2012 +0000
@@ -0,0 +1,94 @@
+/** IoT Gateway Output definition for Open Energy Monitor emonCms 
+ *
+ * @author Andrew Lindsay
+ *
+ * @section LICENSE
+ *
+ * Copyright (c) 2012 Andrew Lindsay (andrew [at] thiseldo [dot] co [dot] uk)
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ * 
+ * @section DESCRIPTION
+ * 
+ * 
+ */
+ 
+#ifndef _OUTPUTEMONCMS_H
+#define _OUTPUTEMONCMS_H
+
+#include "mbed.h"
+#include "HTTPClient.h"
+#include "HTTPText.h"
+
+#define DATABUF_SIZE 128
+
+#define EMONCMS_URL "http://api.pachube.com/v2/feeds/%d.csv?_method=PUT"
+
+/** Output definition class for sending readings to OpenEnergyMonitor emonCms
+ */
+class OutputEmonCms {
+public:
+    /** Default Constructor
+     */
+    OutputEmonCms();
+
+    /** Alternative Constructor
+     *
+     * @param internalBufferStart An internal buffer used to build up requests.
+     * @param url  Pointer to API Url
+     * @param key  Pointer to API key
+     */
+    OutputEmonCms( char *internalBufferStart, char *url, char *key );
+    
+    /** Set the API Key to use for sending readings to Pachube
+     * 
+     * @param key  Pointer to API key
+     */
+//    void setApiKey( char *key );
+
+    /** Initialise output definition object
+     */
+    virtual void init();
+    
+    /** Add a character pointer reading to output 
+     * 
+     * @param dataFeed The feed to update
+     * @param dataStream The data stream within the feed to update or null if no feed
+     * @param reading The new value
+     */
+    virtual void addReading(char *dataFeed, char *dataStream, char *reading );
+    
+    /** Send any collected readings to the api
+     * 
+     * @returns -1 for fail, 1 for success
+     */
+    virtual int send();
+
+protected:
+    int sendCount;
+    // OEM config
+    char *apiUrl;
+    char *apiKey;
+    char *dataBuffer;
+    char *dbufPtr;
+    bool hasData;
+    
+};
+
+#endif /* _OUTPUTEMONCMS_H */
\ No newline at end of file
--- a/Outputs/OutputPachube.cpp	Fri Apr 20 19:32:34 2012 +0000
+++ b/Outputs/OutputPachube.cpp	Tue May 01 21:43:40 2012 +0000
@@ -39,10 +39,17 @@
     sendCount = 0;
 }
 
-void OutputPachube::setApiKey( char *key ) {
+/** Alternative Constructor
+  */
+OutputPachube::OutputPachube( char *internalBufferStart, char *url, char *key ) {
+    sendCount = 0;
+    dataBuffer = internalBufferStart;
+    apiUrl = url;
     apiKey = key;
-    init();
+    dbufPtr = dataBuffer;
+    *dbufPtr = '\0';
 }
+    
 
 void OutputPachube::init( ) {
     dbufPtr = dataBuffer;
@@ -64,23 +71,23 @@
 
 int OutputPachube::send( void ) {
     char urlBuf[64];
-    HTTPClient pachubeHttp;
+    HTTPClient http;
 
     if ( strlen( dataBuffer ) > 1 ) {
-        pachubeHttp.setRequestHeader("X-PachubeApiKey", apiKey);
+        http.setRequestHeader("X-PachubeApiKey", apiKey);
 
         HTTPText csvContent("text/csv");
         // Get the string for Pachube
         csvContent.set(std::string(dataBuffer));
 
         // uri for post includes feed ID and datastream ID
-        snprintf(urlBuf, 64, "http://api.pachube.com/v2/feeds/%d.csv?_method=PUT", currentFeed );
+        snprintf(urlBuf, 64, PACHUBE_URL, currentFeed );
         printf("URL: %s\n",urlBuf);
 
 
         activityLED = 1;
         // result should be 0 and response should be 200 for successful post
-        printf("Send count %d\n", ++sendCount);
+        printf("Pachube Send count %d\n", ++sendCount);
 
         printf("\nHEAP STATS\n");
         __heapstats((__heapprt)fprintf,stderr);
@@ -89,13 +96,15 @@
         printf("\nStackP: %ld\n",__current_sp());
         printf("---------------\n");
 
-        HTTPResult result = pachubeHttp.post(urlBuf, csvContent, NULL);
-        int response = pachubeHttp.getHTTPResponseCode();
+        HTTPResult result = http.post(urlBuf, csvContent, NULL);
+        int response = http.getHTTPResponseCode();
         printf("updateDataStream(%d)\n", response );
         activityLED = 0;
     }
 
-    init();
+    dbufPtr = dataBuffer;
+    *dbufPtr = '\0';
+    
     return 0;
 }
 
--- a/Outputs/OutputPachube.h	Fri Apr 20 19:32:34 2012 +0000
+++ b/Outputs/OutputPachube.h	Tue May 01 21:43:40 2012 +0000
@@ -38,6 +38,8 @@
 
 #define DATABUF_SIZE 128
 
+#define PACHUBE_URL "http://api.pachube.com/v2/feeds/%d.csv?_method=PUT"
+
 /** Output definition class for sending readings to Pachube
  */
 class OutputPachube {
@@ -45,12 +47,20 @@
     /** Default Constructor
      */
     OutputPachube();
+
+    /** Alternative Constructor
+     *
+     * @param internalBufferStart An internal buffer used to build up requests. 
+     * @param url  Pointer to API Url
+     * @param key  Pointer to API key
+     */
+    OutputPachube( char *internalBufferStart, char *url, char *key );
     
     /** Set the API Key to use for sending readings to Pachube
      * 
      * @param key  Pointer to API key
      */
-    void setApiKey( char *key );
+//    void setApiKey( char *key );
 
     /** Initialise output definition object
      */
@@ -71,11 +81,11 @@
     virtual int send();
 
 protected:
-    bool newReading;
     int sendCount;
     // Pachube config
+    char *apiUrl;
     char *apiKey;
-    char dataBuffer[DATABUF_SIZE];
+    char *dataBuffer;       // Pointer to start of databuffer
     char *dbufPtr;
     int currentFeed;
 };
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Outputs/OutputSenSe.cpp	Tue May 01 21:43:40 2012 +0000
@@ -0,0 +1,110 @@
+/** IoT Gateway Output definition for Sen.Se
+ *
+ * @author Andrew Lindsay
+ *
+ * @section LICENSE
+ *
+ * Copyright (c) 2012 Andrew Lindsay (andrew [at] thiseldo [dot] co [dot] uk)
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ * 
+ * @section DESCRIPTION
+ * 
+ * 
+ */
+
+#include "mbed.h"
+#include "OutputSenSe.h"
+
+DigitalOut senseActivityLED(p29, "activityLED");
+
+// Constructor
+OutputSenSe::OutputSenSe() {
+    sendCount = 0;
+}
+
+/** Alternative Constructor
+  */
+OutputSenSe::OutputSenSe( char *internalBufferStart, char *url, char *key ) {
+    sendCount = 0;
+    dataBuffer = internalBufferStart;
+    apiUrl = url;
+    apiKey = key;
+    init();
+}
+
+
+void OutputSenSe::init( ) {
+    dbufPtr = dataBuffer;
+    *dbufPtr = '\0';
+}
+
+/*
+  {
+    "feed_id": <another_feed_id>,
+    "value": <another_event_value>
+  }
+*/
+
+void OutputSenSe::addReading(char *dataFeed, char *dataStream, char *reading ) {
+
+    snprintf(dataBuffer, DATABUF_SIZE, "{ \"feed_id\" : %s, \"value\" : \"%s\" }\n", dataFeed, reading);
+    printf("%s\n",dataBuffer);
+    send();
+}
+
+
+int OutputSenSe::send( void ) {
+    char urlBuf[128];
+    HTTPClient http;
+
+    if ( strlen( dataBuffer ) > 1 ) {
+
+        HTTPText csvContent("application/json");
+        // Get the string for Pachube
+        csvContent.set(std::string(dataBuffer));
+
+        // uri for post includes feed ID and datastream ID
+        snprintf(urlBuf, 128, apiUrl, apiKey );
+        printf("URL: %s\n",urlBuf);
+
+
+        senseActivityLED = 1;
+        // result should be 0 and response should be 200 for successful post
+        printf("Sen.Se Send count %d\n", ++sendCount);
+
+/*        printf("\nHEAP STATS\n");
+        __heapstats((__heapprt)fprintf,stderr);
+        printf("\nHEAP CHECK\n");
+        __heapvalid((__heapprt)fprintf,stderr, 0);
+        printf("\nStackP: %ld\n",__current_sp());
+        printf("---------------\n");
+*/
+        HTTPResult result = http.post(urlBuf, csvContent, NULL);
+        int response = http.getHTTPResponseCode();
+        printf("updateDataStream(%d)\n", response );
+        senseActivityLED = 0;
+    }
+
+    dbufPtr = dataBuffer;
+    *dbufPtr = '\0';
+    
+    return 0;
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Outputs/OutputSenSe.h	Tue May 01 21:43:40 2012 +0000
@@ -0,0 +1,93 @@
+/** IoT Gateway Output definition for Sen.Se
+ *
+ * @author Andrew Lindsay
+ *
+ * @section LICENSE
+ *
+ * Copyright (c) 2012 Andrew Lindsay (andrew [at] thiseldo [dot] co [dot] uk)
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ * 
+ * @section DESCRIPTION
+ * 
+ * 
+ */
+ 
+#ifndef _OUTPUTSENSE_H
+#define _OUTPUTSENSE_H
+
+#include "mbed.h"
+#include "HTTPClient.h"
+#include "HTTPText.h"
+
+#define DATABUF_SIZE 128
+
+#define SENSE_URL "http://api.pachube.com/v2/feeds/%d.csv?_method=PUT"
+
+/** Output definition class for sending readings to Pachube
+ */
+class OutputSenSe {
+public:
+    /** Default Constructor
+     */
+    OutputSenSe();
+
+    /** Alternative Constructor
+     *
+     * @param internalBufferStart An internal buffer used to build up requests. 
+     * @param url  Pointer to API Url
+     * @param key  Pointer to API key
+     */
+    OutputSenSe( char *internalBufferStart, char *url, char *key );
+    
+    /** Set the API Key to use for sending readings to Pachube
+     * 
+     * @param key  Pointer to API key
+     */
+//    void setApiKey( char *key );
+
+    /** Initialise output definition object
+     */
+    virtual void init();
+    
+    /** Add a character pointer reading to output 
+     * 
+     * @param dataFeed The feed to update
+     * @param dataStream The data stream within the feed to update or null if no feed
+     * @param reading The new value
+     */
+    virtual void addReading(char *dataFeed, char *dataStream, char *reading );
+    
+    /** Send any collected readings to the api
+     * 
+     * @returns -1 for fail, 1 for success
+     */
+    virtual int send();
+
+protected:
+    int sendCount;
+    // Sen.Se config
+    char *apiUrl;
+    char *apiKey;
+    char *dataBuffer;       // Pointer to start of databuffer
+    char *dbufPtr;
+    int currentFeed;
+};
+
+#endif /* _OUTPUTSENSE_H */
\ No newline at end of file
--- a/Routing/IoTRouting.cpp	Fri Apr 20 19:32:34 2012 +0000
+++ b/Routing/IoTRouting.cpp	Tue May 01 21:43:40 2012 +0000
@@ -75,6 +75,12 @@
         case  OUTPUT_TYPE_MQTT:
             pr->output = mqttOutput;
             break;
+        case  OUTPUT_TYPE_EMONCMS:
+            pr->output = emonCmsOutput;
+            break;
+        case  OUTPUT_TYPE_SENSE:
+            pr->output = senSeOutput;
+            break;
         default:
             pr->output = NULL;
             break;
@@ -239,6 +245,12 @@
         case  OUTPUT_TYPE_MQTT:
             mqttOutput = output;
             break;
+        case  OUTPUT_TYPE_EMONCMS:
+            emonCmsOutput = output;
+            break;
+        case  OUTPUT_TYPE_SENSE:
+            senSeOutput = output;
+            break;
         default:
             break;
     }
--- a/Routing/IoTRouting.h	Fri Apr 20 19:32:34 2012 +0000
+++ b/Routing/IoTRouting.h	Tue May 01 21:43:40 2012 +0000
@@ -37,6 +37,8 @@
 #include "OutputDef.h"
 #include "OutputPachube.h"
 #include "OutputMqtt.h"
+#include "OutputEmonCms.h"
+#include "OutputSenSe.h"
 #include "PayloadV1.h"
 #include "PayloadV2.h"
 #include "PayloadSimple.h"
@@ -56,6 +58,8 @@
 #define OUTPUT_UNKNOWN 0
 #define OUTPUT_TYPE_PACHUBE 1
 #define OUTPUT_TYPE_MQTT 2
+#define OUTPUT_TYPE_EMONCMS 3
+#define OUTPUT_TYPE_SENSE 4
 
 /** Routing definition for a reading
  * Input source, node ID, sensor ID, output
@@ -174,7 +178,8 @@
     int sendCount;
     OutputDef *pachubeOutput;
     OutputDef *mqttOutput;
-//    IpAddr serverIpAddr(192,168,1,77);
+    OutputDef *emonCmsOutput;
+    OutputDef *senSeOutput;
 
     std::vector<PayloadRouting*> _routing;
     std::vector<IoTNodeDef*> _nodeDefList;
--- a/main.cpp	Fri Apr 20 19:32:34 2012 +0000
+++ b/main.cpp	Tue May 01 21:43:40 2012 +0000
@@ -36,7 +36,6 @@
  * Sample configuration file IOTSETUP.TXT
  *
  * @code
- * pachube.key=***your pachube api key***
  * ip.mode=fixed
  * ip.address=192.168.1.99
  * ip.netmask=255.255.255.0
@@ -48,6 +47,12 @@
  * time.host=0.uk.pool.ntp.org
  * time.timezone=GMT
  * time.dst=yes
+ * pachube.key=***your Pachube api key***
+ * pachube.apiurl=http://api.pachube.com/v2/feeds/%d.csv?_method=PUT
+ * emoncms.key=***your emonCms api key***
+ * emoncms.apiurl=http://your.host.com/emoncms/api/post?apikey=%s&json=
+ * sense.key=***your Sen.se api key***
+ * sense.apiurl=http://api.sen.se/events/?sense_key=%s
  * mqtt.host=
  * mqtt.port=1883
  * mqtt.username=
@@ -70,7 +75,7 @@
 
 using std::string;
 
-#define VERSION_INFO "IoT Gateway Basic - Version 0.6-BETA "
+#define VERSION_INFO "IoT Gateway Basic - Version 0.7-BETA "
 
 DigitalOut heartbeatLED(LED1, "heartbeatLED");
 DigitalOut led2(LED2, "led2");
@@ -101,10 +106,14 @@
 #define MAX_LINE_LENGTH 128
 __attribute((section("AHBSRAM0"))) static char lineBuf[MAX_LINE_LENGTH];
 __attribute((section("AHBSRAM0"))) static OutputPachube outPachube;
+__attribute((section("AHBSRAM0"))) static OutputEmonCms outEmonCms;
+__attribute((section("AHBSRAM0"))) static OutputSenSe outSenSe;
 __attribute((section("AHBSRAM0"))) static IoTRouting rtr;
 
 // Pachube config
+__attribute((section("AHBSRAM0"))) char pachubeApiUrl[128];
 __attribute((section("AHBSRAM0"))) char pachubeApiKey[65];
+__attribute((section("AHBSRAM0"))) char pachubeDataBuffer[200];
 
 // MQTT config
 __attribute((section("AHBSRAM0"))) IpAddr mqttHostAddress( 0, 0, 0, 0);
@@ -115,10 +124,19 @@
 
 //char mqttHostName[65];
 
+// Open energy Monitor emonCMS config
+__attribute((section("AHBSRAM0"))) char emonCmsApiUrl[128];
+__attribute((section("AHBSRAM0"))) char emonCmsApiKey[65];
+__attribute((section("AHBSRAM0"))) char emonCmsDataBuffer[200];
+
+// Open energy Monitor Sen.Se config
+__attribute((section("AHBSRAM0"))) char senSeApiUrl[128];
+__attribute((section("AHBSRAM0"))) char senSeApiKey[65];
+__attribute((section("AHBSRAM0"))) char senSeDataBuffer[200];
+
 // Time server config
 __attribute((section("AHBSRAM0"))) char ntpHost[MAX_LINE_LENGTH] = "0.uk.pool.ntp.org";
 
-
 // RFM12B config
 __attribute((section("AHBSRAM0"))) static string rfm12bBands[4] = {"xxx", "433", "868", "915" };
 __attribute((section("AHBSRAM0"))) static uint8_t rfm12bId;
@@ -229,9 +247,9 @@
     // read file
     while (!feof( fp )) {
         fgets(lineBuf,MAX_LINE_LENGTH,fp);
-        printf("[%s] ",lineBuf);
+//        printf("[%s] ",lineBuf);
         trim( lineBuf );
-        printf("[%s]\n", lineBuf);
+//        printf("[%s]\n", lineBuf);
 
         // Need to read each entry and update config
         char *nameStr;
@@ -263,9 +281,23 @@
             }  else if ( strcmp( nameStr, "time.host" ) == 0 ) {
                 strcpynull(ntpHost, valueStr );
 
+            }  else if ( strcmp( nameStr, "pachube.apiurl" ) == 0 ) {
+                strcpynull(pachubeApiUrl, valueStr );
+
             }  else if ( strcmp( nameStr, "pachube.key" ) == 0 ) {
                 strcpynull(pachubeApiKey, valueStr );
 
+            }  else if ( strcmp( nameStr, "emoncms.apiurl" ) == 0 ) {
+                strcpynull(emonCmsApiUrl, valueStr );
+
+            }  else if ( strcmp( nameStr, "emoncms.key" ) == 0 ) {
+                strcpynull(emonCmsApiKey, valueStr );
+
+            }  else if ( strcmp( nameStr, "sense.apiurl" ) == 0 ) {
+                strcpynull(senSeApiUrl, valueStr );
+
+            }  else if ( strcmp( nameStr, "sense.key" ) == 0 ) {
+                strcpynull(senSeApiKey, valueStr );
             } else if ( strcmp( nameStr, "mqtt.host" ) == 0 ) {
                 setIpAddress( &tmpAddress[0], valueStr );
                 mqttHostAddress = IpAddr( tmpAddress[0],tmpAddress[1],tmpAddress[2],tmpAddress[3]);
@@ -419,14 +451,26 @@
     time_t ctTime = time(NULL);
     printf("\nTime is now (UTC): %s\n", ctime(&ctTime));
 
+    // If Pachube API Key defined, set up output module
     if ( strlen(pachubeApiKey) > 0 ) {
-        // Only add Pachube output if a key has been defined
-        outPachube = OutputPachube();
-        outPachube.setApiKey( pachubeApiKey );
+        outPachube = OutputPachube( pachubeDataBuffer, pachubeApiUrl, pachubeApiKey );
+//        outPachube.setApiKey( pachubeApiKey );
 //        printf("MAIN: outPachube = %ld\n",(int)&outPachube);
         rtr.addOutput( (OutputDef*)&outPachube , OUTPUT_TYPE_PACHUBE);
     }
 
+    // If emonCms API Key defined, set up output module
+    if ( strlen(emonCmsApiKey) > 0 ) {
+        outEmonCms = OutputEmonCms( emonCmsDataBuffer, emonCmsApiUrl, emonCmsApiKey );
+        rtr.addOutput( (OutputDef*)&outEmonCms , OUTPUT_TYPE_EMONCMS);
+    }
+
+    // If Sen.se API Key defined, set up output module
+    if ( strlen(senSeApiKey) > 0 ) {
+        outSenSe = OutputSenSe( senSeDataBuffer, senSeApiUrl, senSeApiKey );
+        rtr.addOutput( (OutputDef*)&outSenSe , OUTPUT_TYPE_SENSE);
+    }
+
     //mqttHostAddress = IpAddr(192,168,1,77);
     OutputMqtt outMqtt = OutputMqtt();
 //    mqttHostAddress = resolver.resolveName("api.pachube.com");